最近在做一个本地的漫画项目,因为没有到网络,所有的漫画资源都存在assets下,也正好趁此机会来总结一下Assets文件的使用,要不大家一起来看看测测,你到底了解Assets多少
assets和res/raw资源文件的区别
1 . res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;
assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2 . res/raw不可以有目录结构,
而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
assets和res/raw资源文件的使用
*读取文件资源:
1 . 读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作
InputStream is = getResources().openRawResource(R.id.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));
当然这是比较理想的情况了,当assets里面有目录结构时,问题就稍微的复杂了,那么接下来我们来看一个:
关于assets内漫画书的实例
首先我们来看看assets下目录结构图:
可以清楚地发现里面包含了三层目录结构,下面我们来想象一个用例:将一本漫画书里的某集中的漫画一张张展示出来,比如说展示在RecyclerView上
我们要考虑的第一个问题是:如何拿到每一张漫画
这里有几种拿法:
1).首先是直接以流的形式一张张读取:
/**
* 获得某书某集的某张图片
* @param context
* @param bookId
* @param section
* @param page
* @return
*/
private static Bitmap getPageBitmap(Context context, String bookId,Integer section, Integer page){
Bitmap bitmap=null;
String path;
if (section<10){
path=bookId+"/"+"0"+section+"/"+"00"+page+".jpg";
}else {
path=bookId+"/"+section+"/"+"00"+page+".jpg";
}
try {
InputStream in = context.getResources().getAssets().open(path);//不需要加“assets”
bitmap = BitmapFactory.decodeStream(in);
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
这样就是拼凑出路径,然后调用getResources().getAssets().open(path)这个方法拿到读入流,然后再调用BitmapFactory.decodeStream(in)这个方法将流转化成Bitmap对象,然后返回;
2).第二种方法就是使用框架:比如说Imageloader。使用框架就比较简单,就是拼凑出路径,然后调用 ImageLoader.getInstance().loadImage(url, SimpleImageLoadingListener)来加载
ImageLoader.getInstance().loadImage(url, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view,Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
imageView.setImageBitmap(loadedImage);
}
});
好了现在既然能拿到每一个单张的图片,然后就是要去拿某集所有图片的集合了:
这里就又出现了一个问题,每集的漫画的张数都不是固定的,我们不能一张张去数吧,书少的时候还好说,当来个十几本书,每本书再来个十几集,我想没几个人受得了,主要是这样也不科学,
确实assets确实有提供这样的方法来得到文件夹或文件的个数。
/**
* 获得某书的集数
*
* @param context
* @param book
* @return
*/
public static int getBookSectionCount(Context context, String book) {
int sectionCount = 0;
AssetManager asserter = context.getAssets();
String[] bookDirs = null;
try {
// 0,1等目录下必须要有文件,才能被list出来。
bookDirs = asserter.list(book);
sectionCount = bookDirs.length;
} catch (IOException e) {
e.printStackTrace();
sectionCount = 0;
}
return sectionCount;
}
从上面的代码不难发现通过AssetManager.list()方法就可以获得目录下所有文件或文件夹名的数组,
上面的代码我们获得的二层文件夹名的数组,要拿到文件夹得个数只需要数组.length就可以了,
同理我们也可以拿到每集的漫画张数,见代码:
/**
* 获得某书某集的页数
*
* @param context
* @param book
* @param section
* @return
*/
public static int getSectionPageCount(Context context, String book, String section) {
int pageCount = 0;
AssetManager asserter = context.getAssets();
try {
String[] pages = asserter.list(book + "/" + section);
pageCount = pages.length;
} catch (IOException e) {
e.printStackTrace();
pageCount = 0;
}
return pageCount;
}
拿到文件或文件夹得数量主要是使用文件名和文件名的个数,而上面再拼凑路径的时候我们并没有用文件名的集合,其实是不应该的,我想也没啥难度,既然刚开始没想到,下次记住有这种方便的写法就ok了,感兴趣的朋友可以自己去写写。
拿到文件名和长度后,最后我们就可以拿到某集的漫画集合了,直接见代码:
/**
* 使用流的形式获得某本书的某集下所有的图片资源
* @param context
* @param bookId
* @param section
* @return
*/
public static List<Bitmap> getAssetsSectionList(Context context, String bookId, Integer section) {
List<Bitmap> bitmapList=new ArrayList<>();
String sectionName=null;
if (section<10){
sectionName="0"+section;
}else {
sectionName=""+section;
}
int count= BookLibs.getSectionPageCount(context,bookId,sectionName);
for (int i=1;i<count+1;i++){
Bitmap bitmap=getPageBitmap(context,bookId,section,i);
bitmapList.add(bitmap);
}
return bitmapList;
}
这里调用了,获得单张漫画的方法:getPageBitmap(),那下面就来看看代码吧,没有什么难度:
/**
* 获得某书某集的某张图片
* @param context
* @param bookId
* @param section
* @param page
* @return
*/
private static Bitmap getPageBitmap(Context context, String bookId,Integer section, Integer page){
Bitmap bitmap=null;
String path;
if (page<10||page>0){
path=bookId+"/"+"0"+section+"/"+"00"+page+".jpg";
}else {
path=bookId+"/"+section+"/"+"00"+page+".jpg";
}
try {
InputStream in = context.getResources().getAssets().open(path);//不需要加“assets”
bitmap = BitmapFactory.decodeStream(in);
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
由于我这里的文件名比较有规律,所以自己任性自己拼凑的,最好使用前面的文件名的集合,这里就不多说了,前面也贴出了这个方法。
当然如果使用框架来加载本地图片的话其实就更简单了(这里用例是imageloader),只需要拿到路径的集合就OK:
public static List<String> getSectionImagePathList(Context context,String bookId,Integer section){
List<String> pathList=new ArrayList<>();
String sectionPath=null;
int sectionCount=BookLibs.getBookSectionCount(context,bookId);
if (section<10){
sectionPath="0"+section;
}else {
sectionPath=""+section;
}
String path;
for (int i=1;i<sectionCount+1;i++) {
path="assets://"+bookId+"/"+sectionPath+"/00"+i+".jpg";
pathList.add(path);
}
return pathList;
}
还是那句话,最好使用前面得到的文件名的数组来拼凑出路径的集合,路径的样式就是:
path="assets://"+bookId+"/"+sectionPath+"/00"+i+".jpg";
前面的assets://是固定写法,后面根据目录结构来定。
最最后或者使用流拿到的漫画集作为RecyclerView的数据源,或者是以每张漫画的路径集合通过imageloader来加载本地图片然后在适配器里设置给RecyclerView的子控件就OK了。