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;
}
}