APK安裝過程
復制APK安裝包到data/app目錄下,解壓並掃描安裝包,把dex文件(Dalvik字節碼)保存到dalvik-cache目錄,並data/data目錄下創建對應的應用數據目錄,Android系統在sdcard上為每一個應用分配了存儲路徑:/sdcard/Android/data/$(應用的包路徑),該路徑可以通過 context.getExternalFilesDir 得到,一般應用卸載的時候,該目錄也會隨之被刪除。
Android資源文件分為兩類:
第一種是res目錄下存放的可編譯的資源文件,編譯時,系統會自動在R.java中生成資源文件的ID,所以訪問這種資源比較簡單,通過在程序中調用R.id.filenam e即可。
另一種是assets目錄下存放的原始資源文件,因為系統在編譯的時候不會編譯assets下的資源文件,所以我們不能通過R.id.filename的方式訪問它們。那我么能不能通過該資源的絕對路徑去訪問它們呢?因為apk安裝之后會放在/data/app/**.apk目錄下,assets被綁定在apk里,以apk形式存在,並不會解壓到/data/data/YourApp目錄下去,所以我們無法直接獲取到assets的絕對路徑,因為它們根本就沒有獨立存在。
res/raw和assets的相同點:
1.兩者目錄下的文件在打包后會原封不動的保存在apk包中,不會被編譯成二進制。
res/raw和assets的不同點:
1.res/raw中的文件會被映射到R.java文件中,訪問的時候直接使用資源ID即R.id.filename;assets文件夾下的文件不會被映射到R.java中,訪問的時候需要AssetManager類。
2.res/raw不可以有目錄結構,而assets則可以有目錄結構(在其目錄下可以再建文件夾)
3.讀取res/raw下的文件資源,通過以下方式獲取輸入流:InputStream is=getResources().openRawResource(R.id.filename); 讀取assets下的文件資源,通過以下方式獲取輸入流:InputStream is =getResources()..getAssets().open("filename");
AssetManager管理對assets文件夾資源的訪問
查看官方API可知,AssetManager提供對應用程序的原始資源文件進行訪問;這個類提供了一個低級別的API=1,它允許你以簡單的字節流的形式打開和讀取和應用程序綁定在一起的原始資源文件。主要用到list()及open()方法。
finalString[] list(Stringpath) 返回指定路徑下的所有文件及目錄名,path是相對路徑,是assets子目錄。
finalInputStream open(String fileName) 使用 ACCESS_STREAMING模式打開assets下的指定文件,fileName是相對路徑,是assets子目錄。
finalInputStream open(String fileName,int accessMode) 使用顯示的訪問模式打開assets下的指定文件。
下面這個類,主要功能是通過遞歸方式,實現對assets下的某個子目錄文件讀取操作,並復制到指定路徑。
-
package com.study.asset;
-
-
import java.io.File;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.io.InputStream;
-
-
import com.study.mylog.MyLog;
-
-
import android.content.Context;
-
import android.content.res.AssetManager;
-
-
public
class AssetsCopy {
-
-
private Context mContext;
-
public AssetsCopy(Context context) {
-
mContext = context;
-
}
-
-
public boolean CopyFiles(String oldPath, String newPath) throws IOException {
-
boolean isCopy =
true;
-
AssetManager mAssetManger = mContext.getAssets();
-
String[] fileNames=mAssetManger.list(oldPath);
// 獲取assets目錄下的所有文件及有文件的目錄名
-
-
if (fileNames.length >
0) {
//如果是目錄,如果是具體文件則長度為0
-
File file =
new File(newPath);
-
file.mkdirs();
//如果文件夾不存在,則遞歸
-
for (String fileName : fileNames) {
-
if(oldPath==
"")
//assets中的oldPath是相對路徑,不能夠以“/”開頭
-
CopyFiles(fileName,newPath+
"/"+fileName);
-
else
-
CopyFiles(oldPath+
"/"+fileName,newPath+
"/"+fileName);
-
}
-
}
else {
//如果是文件
-
InputStream is = mAssetManger.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();
-
}
-
return isCopy;
-
}
-
-
}