在做安卓小項目的時候,一般圖檔都是放在res/drawable檔案夾中,需要通路的時候通過R.drawable.xxxx來通路該圖檔,但是如果項目比較大的話,而圖檔又特别多,那麼如果依然通過R.drawable.xxx來通路圖檔的話,那是相當的累。安卓中,有一個assets目錄,我們可以把圖檔放在這個目錄下,通過I/O流來通路其中的圖檔。
assets和drawable的差別。
相同點:
1.檔案會原封不動的存儲在裝置上,不會被編譯成二進制。
不同點:
1.引用資源方式不同:
drawable中的資源會在R類中生成相應的int型變量。
assets中的資源不會。
故:引用drawable中資源的時候可以通過R.drawable.xxxx的方式引用,而引用assets中資源需要用檔案名引用。
2.子目錄不同:
drawable不能繼續建檔案夾(不能有子檔案夾),但是assets中可以建任意層次的子目錄(操作更加靈活)。
那麼到底如何才能擷取到assets中的資源呢?通過Android提供的AssetManager工具類。
知識儲備:
1.概述:
Provides access to an application's raw asset files; see
Resources
for the way most applications will want to retrieve their resource data. This class presents a lower-level API that allows you to open and read raw files that have been bundled with the application as a simple stream of bytes.
這是API裡面寫的,大概意思是,提供一個通路對原始資源檔案進行通路的方式。應用程式使用該方式檢視資源,大多是要擷取資源中的資料。這個類提供了一個較低的API允許你以簡單的位元組流打開和讀取和應用程式綁定在一起的資源檔案(自行翻譯,一切以原文為準)。
2.常用方法:
String[] | list(String path) 傳回指定路徑下的所有檔案及目錄名 |
InputStream | open(String fileName) 使用ACCESS_STREAMING模式打開 |
InputStream | open(String fileName ,int accessMode) 使用顯示的通路模式打開assets下的指定檔案 |
3.使用
3.1加載網頁
WebView w;
w.loadUrl(url);
3.2通路檔案
InputStream is = getAssets().open(fileName);
3.3擷取檔案和目錄名
String fileNames[] = content.getAssets().list(path);
3.4将檔案複制到SD卡(感覺沒什麼用,但是處于知識的完整性,這裡還是給出代碼,有興趣的可以自己看看)
/**
* 從assets目錄中複制整個檔案夾内容
* @param context Context 使用CopyFiles類的Activity
* @param oldPath String 原檔案路徑 如:/aa
* @param newPath String 複制後路徑 如:xx:/bb/cc
*/
public void copyFilesFassets(Context context,String oldPath,String newPath) {
try {
String fileNames[] = context.getAssets().list(oldPath);//擷取assets目錄下的所有檔案及目錄名
if (fileNames.length > 0) {//如果是目錄
File file = new File(newPath);
file.mkdirs();//如果檔案夾不存在,則遞歸
for (String fileName : fileNames) {
copyFilesFassets(context,oldPath + "/" + fileName,newPath+"/"+fileName);
}
} else {//如果是檔案
InputStream is = context.getAssets().open(oldPath);
FileOutputStream fos = new FileOutputStream(new File(newPath));
byte[] buffer = new byte[1024];
int byteCount=0;
while((byteCount=is.read(buffer))!=-1) {//循環從輸入流讀取 buffer位元組
fos.write(buffer, 0, byteCount);//将讀取的輸入流寫入到輸出流
}
fos.flush();//重新整理緩沖區
is.close();
fos.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//如果捕捉到錯誤則通知UI線程
MainActivity.handler.sendEmptyMessage(COPY_FALSE);
}
}