天天看點

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了。