最近在做一個本地的漫畫項目,因為沒有到網絡,所有的漫畫資源都存在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<){
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了。