讀取assets下的配置檔案
這裡講assets或者res/raw中的資源也當做成一種儲存資源。只是這個儲存資源是在程式執行之前就儲存好了的。比如,app需要所有的城市和城市的編碼,用於使用者的選擇當前城市。這個時候的所有的城市列表從網路當中獲取,不太合適,還不如自己在儲存一個xml格式的檔案,其中有所有的城市列表。從中讀取出來。再比如,在實際開發中,後臺只傳來了一些ABC001,ABC002,這樣的編碼,需要自己去儲存一個關係,一個字典。最簡單的方式是直接在程式碼中寫死,這個不推薦,資料一多,程式碼就會很長,直接寫死,讓人感覺是個很low的寫法,這個時候就去做一個xml配置檔案。其實,實際開發中,有很多需要自己寫一個配置檔案的,而這些配置檔案就可以使用xml格式,並儲存在assets上。也可以放入raw中。
那麼先比較一些assets和res/raw有什麼區別?
*res/raw和assets的相同點:
1.兩者目錄下的檔案在打包後會原封不動的儲存在apk包中,不會被編譯成二進位制。
*res/raw和assets的不同點:
1.res/raw中的檔案會被對映到R.java檔案中,訪問的時候直接使用資源ID即R.id.filename;assets資料夾下的檔案不會被對映到R.java中,訪問的時候需要AssetManager類。
2.res/raw不可以有目錄結構,而assets則可以有目錄結構,也就是assets目錄下可以再建立資料夾
*讀取檔案資源:
1.讀取res/raw下的檔案資源,通過以下方式獲取輸入流來進行寫操作
- InputStream is = getResources().openRawResource(R.raw.filename);
2.(1)讀取assets下的檔案資源,通過以下方式獲取輸入流來進行寫操作
- AssetManager am =null;
- am = getAssets();
- InputStream is = am.open("filename");
(2)如果用Videoview來播放:
VideoView.setVideoUri(Uri.parse("android.resource://" + getpackageName() + "/" + R.raw.movie));
注意1:Google的Android系統處理Assert有個bug,在AssertManager中不能處理單個超過1MB的檔案,不然會報異常,raw沒這個限制可以放個4MB的Mp3檔案沒問題。
注意2:assets 資料夾是存放不進行編譯加工的原生檔案,即該資料夾裡面的檔案不會像 xml, java 檔案被預編譯,可以存放一些圖片,html,js, css 等檔案。
接下來如何對獲取xml檔案進行解析這裡講介紹sax和pull解析方式。
首先來看Sax解析。
<?xml version="1.0" encoding="utf-8"?>
<city>
<country id="420100" name="武漢市"/>
<country id="420200" name="黃石市"/>
<country id="420300" name="十堰市"/>
<country id="420500" name="宜昌市"/>
<country id="420600" name="襄陽市"/>
<country id="420700" name="鄂州市"/>
<country id="420800" name="荊門市"/>
<country id="420900" name="孝感市"/>
<country id="421000" name="荊州市"/>
<country id="421100" name="黃岡市"/>
<country id="421200" name="咸寧市"/>
<country id="421300" name="隨州市"/>
<country id="422800" name="恩施州"/>
<country id="429004" name="仙桃市"/>
<country id="429005" name="潛江市"/>
<country id="429006" name="天門市"/>
<country id="429021" name="神農架林區"/>
<country id="429900" name="省直"/>
</city>
並見一個實體類
public class CityBean {
private String cityId;
private String cityName;
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}
建立之後,這裡直接給出程式碼
public class CitySaxParseHandler extends DefaultHandler{
private ArrayList<CityBean> mCityBeen;
private CityBean city;
private String tagName;
public static ArrayList<CityBean> getProvicenModel(InputStream in) throws Exception {
//獲取SAXParseFactory工廠
SAXParserFactory factory = SAXParserFactory.newInstance();
//獲取解析器
SAXParser parser = factory.newSAXParser();
//獲取xml讀取器
XMLReader reader = parser.getXMLReader();
//將InputStream流包裝成InputSource
InputSource is = new InputSource(in);
//獲取DefaultHandler
CitySaxParseHandler handler = new CitySaxParseHandler();
//讀取器設定內容
reader.setContentHandler(handler);
//解析流
reader.parse(is);
return handler.mCityBeen;
}<span style="white-space:pre"> </span>//當SAX解析器開始解析xml呼叫該方法
@Override
public void startDocument() throws SAXException {
super.startDocument();
}
//當sax解析器解析到xml文件結束時呼叫
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
//解析到開始標籤的時候呼叫如解析到<city>
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
this.tagName = localName;
if (tagName.equalsIgnoreCase("city")){
mCityBeen = new ArrayList<>();
}else if(tagName.equalsIgnoreCase("country")){
city = new CityBean();
city.setCityId(attributes.getValue("id"));
city.setCityName(attributes.getValue("name"));
}
}
//解析到結束標籤的時候呼叫如</city>
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
this.tagName = null;
if (localName.equalsIgnoreCase("city")){
}else if(localName.equalsIgnoreCase("country")){
mCityBeen.add(city);
city = null;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
}
來看看getProvicenModel()裡面的步驟如下:
1、例項化一個工廠SAXParserFactory
2、例項化SAXPraser物件,建立XMLReader 解析器
3、例項化handler,處理器
4、解析器註冊一個事件
4、讀取檔案流
5、解析檔案
接下下看看pull解析方式,public List<CityBean> parseXml(InputStream in) throws Exception{
List<CityBean> cityBeenList = null ;
CityBean city = null;
XmlPullParser xmlPullParser = Xml.newPullParser();
xmlPullParser.setInput(in,"UTF-8");
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT){
switch (eventType){
case XmlPullParser.START_DOCUMENT: //文件開始
break;
case XmlPullParser.START_TAG: //開始標籤
if ("city".equalsIgnoreCase(xmlPullParser.getName())){
cityBeenList = new ArrayList<>();
}else if("country".equalsIgnoreCase(xmlPullParser.getName())){
city = new CityBean();
//如果xml檔案<city>武漢</city>,這裡xmlPullParser.getText();獲取其值
city.setCityId(xmlPullParser.getAttributeValue(null,"id"));
city.setCityName(xmlPullParser.getAttributeValue(null,"name"));
}
break;
case XmlPullParser.END_TAG: //結束標籤
if ("city".equalsIgnoreCase(xmlPullParser.getName())){
} else if ("country".equalsIgnoreCase(xmlPullParser.getName())){
cityBeenList.add(city);
city = null;
}
break;
}
eventType = xmlPullParser.next(); // 進入下一個元素並觸發相應事件
}
return cityBeenList;
}
assets res/raw檔案就到這裡,下面一個工具類,就是獲取其中的資源並轉化成字串。
public class ResourceUtil {
/**
* 讀取assets中的檔案
* @param fileName 檔名
* @return
*/
public static String getFileFromAssets(String fileName) {
if (TextUtils.isEmpty(fileName)) {
return null;
}
try {
StringBuilder sb = new StringBuilder("");
InputStreamReader in = new InputStreamReader(SheBaoApp.getContext().getResources().getAssets().open(fileName));
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 讀取raw中的檔案
* @param resid
* @return
*/
public static String getFileFromRaw(int resid) {
try {
StringBuffer sb = new StringBuffer("");
InputStreamReader in = new InputStreamReader(SheBaoApp.getContext().getResources().openRawResource(resid));
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static InputStream getAssert(Context context,String name){
try {
InputStream inputStream = context.getAssets().open(name);
return inputStream;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}