这里讲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;
}
}