Android培訓班(66)dex檔案開啟流程
下面來分析這個函式程式碼,如下:
intdexZipPrepArchive(int fd, const char* debugFileName, ZipArchive*pArchive)
{
這個函式輸入檔案控制代碼、檔名稱、壓縮檔案物件。
MemMapping map;
int err;
map.addr = NULL;
memset(pArchive, 0, sizeof(*pArchive));
pArchive->mFd = fd;
這行程式碼是儲存檔案控制代碼。
if (sysMapFileInShmem(pArchive->mFd,&map) != 0) {
err = -1;
LOGW("Map of '%s' failed\n",debugFileName);
goto bail;
}
if (map.length < kEOCDLen) {
err = -1;
LOGV("File '%s' too small to be zip(%zd)\n", debugFileName,map.length);
goto bail;
}
這段程式碼對映檔案資料到記憶體。
if (!parseZipArchive(pArchive, &map)) {
err = -1;
LOGV("Parsing '%s' failed\n",debugFileName);
goto bail;
}
這段程式碼是分析zip檔案。
/* success */
err = 0;
sysCopyMap(&pArchive->mMap, &map);
map.addr = NULL;
這段程式碼拷貝到對映位置。
bail:
if (err != 0)
dexZipCloseArchive(pArchive);
if (map.addr != NULL)
sysReleaseShmem(&map);
return err;
}
函式dexZipPrepArchive的處理,主要就是先儲存檔案控制代碼,然後建立檔案記憶體對映,呼叫parseZipArchive函式來分析zip的所有入口點,並記錄到相應的hash表裡,最後呼叫sysCopyMap函式來儲存到zip檔案物件結構裡。
由上面分析可知,dex檔案是壓縮成zip檔案,這樣可以減少佔用空間。dex檔案在系統裡是怎麼樣開啟的過程呢?其它經過下面的過程:
1)系統初始化虛擬機器時,會初始化原始方法gDvmNativeMethodSet集合。
2)在原始方法集合裡有一個函式集合dvm_dalvik_system_DexFile,註冊它為Ldalvik/system/DexFile串,當虛擬機器呼叫DexFile相關函式時,就會呼叫這些函式來處理Dex檔案。
3)在處理Dex檔案時,會呼叫函式集合:dvm_dalvik_system_DexFile,這個函式集合裡,主要有如下函式:
constDalvikNativeMethod dvm_dalvik_system_DexFile[] = {
{"openDexFile", "(Ljava/lang/String;Ljava/lang/String;I)I",
Dalvik_dalvik_system_DexFile_openDexFile},
{"closeDexFile", "(I)V",
Dalvik_dalvik_system_DexFile_closeDexFile},
{"defineClass", "(Ljava/lang/String;Ljava/lang/ClassLoader;ILjava/security/ProtectionDomain;)Ljava/lang/Class;",
Dalvik_dalvik_system_DexFile_defineClass},
{"getClassNameList", "(I)[Ljava/lang/String;",
Dalvik_dalvik_system_DexFile_getClassNameList},
{"isDexOptNeeded", "(Ljava/lang/String;)Z",
Dalvik_dalvik_system_DexFile_isDexOptNeeded},
{NULL, NULL, NULL },
};
openDexFile方法對應的原始函式是Dalvik_dalvik_system_DexFile_openDexFile,它是開啟Dex檔案函式。
closeDexFile方法對應的原始函式是Dalvik_dalvik_system_DexFile_closeDexFile,它是關閉已經開啟的Dex檔案函式。
4)在Dalvik_dalvik_system_DexFile_openDexFile函式裡,呼叫函式dvmJarFileOpen開啟JAR或者ZIP壓縮的檔案。
5)在dvmJarFileOpen函式裡,呼叫dexZipOpenArchive來處理ZIP檔案,呼叫dexZipFindEntry函式讀取ZIP解壓的檔案,呼叫dvmDexFileOpenFromFd函式讀取相應的類資料到記憶體,並返回給虛擬機器。