天天看点

Assets资源文件的层级目录的使用案例

最近在做一个本地的漫画项目,因为没有到网络,所有的漫画资源都存在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下目录结构图:

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<){
            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 = ;
        AssetManager asserter = context.getAssets();
        String[] bookDirs = null;
        try {
            // 0,1等目录下必须要有文件,才能被list出来。
            bookDirs = asserter.list(book);
            sectionCount = bookDirs.length;

        } catch (IOException e) {
            e.printStackTrace();
            sectionCount = ;
        }
        return sectionCount;
    }
           

从上面的代码不难发现通过AssetManager.list()方法就可以获得目录下所有文件或文件夹名的数组,

上面的代码我们获得的二层文件夹名的数组,要拿到文件夹得个数只需要数组.length就可以了,

同理我们也可以拿到每集的漫画张数,见代码:

/**
     * 获得某书某集的页数
     *
     * @param context
     * @param book
     * @param section
     * @return
     */
    public static int getSectionPageCount(Context context, String book, String section) {
        int pageCount = ;
        AssetManager asserter = context.getAssets();
        try {
            String[] pages = asserter.list(book + "/" + section);
            pageCount = pages.length;

        } catch (IOException e) {
            e.printStackTrace();
            pageCount = ;
        }
        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<){
            sectionName="0"+section;
        }else {
            sectionName=""+section;
        }
        int count= BookLibs.getSectionPageCount(context,bookId,sectionName);

        for (int i=;i<count+;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<||page>){
            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<){
            sectionPath="0"+section;
        }else {
            sectionPath=""+section;
        }
        String path;
        for (int i=;i<sectionCount+;i++) {
            path="assets://"+bookId+"/"+sectionPath+"/00"+i+".jpg";
            pathList.add(path);
        }
        return pathList;
    }
           

还是那句话,最好使用前面得到的文件名的数组来拼凑出路径的集合,路径的样式就是:

前面的assets://是固定写法,后面根据目录结构来定。

最最后或者使用流拿到的漫画集作为RecyclerView的数据源,或者是以每张漫画的路径集合通过imageloader来加载本地图片然后在适配器里设置给RecyclerView的子控件就OK了。