一個apk包中一般包含以下文件

1、assets目錄:保留工程中asset目錄,其它工程下的、jar包中的asset也會合並到該assets目錄下
assets目錄在工程中主要用於存放一些較大的資源文件,例如:圖片、音樂、字體等。
2、lib目錄:由於編譯的時候jar文件已經合並到主工程中,lib中包含所有的so文件,so目錄的路徑保留原有路徑(CPU類型)
3、META-INF目錄:信息描述,簽名等用途
4、res目錄:工程資源文件,以主工程為主,其它文件合並,values文件將不會出現在此目錄下,因為已經將其編譯到resouces.arsc文件中,raw文件將保持原有內容不會被編譯。
5、AndroidManifest文件:清單文件,用來做組件查找
6、classes.dex文件:所有的class集合,虛擬機執行的文件
7、resources.arsc:系統資源文件索引,包含一些系統信息
安裝過程的時候實際上就是將APK文件放到特定的目錄下,並且生成與此應用有關的文件,應用級的應用一般放到data/app下,系統級應用放到system/app下。
之前有過的一篇講解Resources和AssetManager,這時候資源的路徑就指向了這個apk文件,就可以取得到需要的資源了。dex也是一個道理,dex文件是通過DexClassLoader來加載的,所以也就是如果我們在程序中使用加載器加載指定的dex文件就可以實現動態的加載,Facebook分dex包也是基於這種方式來做的。至於為什么要分多個dex文件,以下給出解釋:
因為一個應用只會擁有越來越多的功能,但隨着工程越來越大,而Android方法數量不能超過65K,如果超出之后,將會拋出Conversion to Dalvik format failed:Unable to execute dex:method ID not in[0,0xffff]65536。由於Android系統中,一個Dex文件中存儲方法的id用的是short類型數據,所以導致你的dex中方法數不能超過65K,在2.3系統之前,虛擬機的內存只分配了5M,所以去掉一些無用的jar包,將一些屬性設置為public,從而可以去掉get/set方法來壓縮方法數量。
---------------------------------------------------------------------------------------------------------------------------------------------------------
講完了apk的構成,那么apk是如何打包生成的呢?
首先android的資源是通過打包工具aapt(Android Assest Package Tool)打包到apk文件中的。在打包之前,大部分文本格式的xml資源文件還會被編譯成二進制格式的xml資源文件,這些xml資源文件之所以要從文本格式編譯成二進制格式,是因為:
1、二進制格式的XML文件占用空間更小。這是由於所有XML元素的標簽、屬性名稱、屬性值和內容所涉及到的字符串都會被統一收集到一個字符串資源池中去,並且會去重。有個這個字符串資源池,原來使用字符串的地方就是被替換成一個索引到字符串資源池的整數值,從而可以減少文件的大小。
2、二進制格式的xml文件解析速度更快。這是由於二進制格式的xml元素里面不再包含有字符串值,因此就避免了進行字符串解析,從而提高速度。
將xml資源文件從文本格式編譯成二進制格式解決了空間占用以及解析效率的問題,但是對於android資源管理框架來說,這只是其中的一部分,android資源管理框架還有個更重要的任務——根據資源ID來快速找到對應的資源。
為了能讓用戶有最好的體驗,為了支持android資源管理框架快速定位最匹配資源,android資源打包工具aapt在編譯和打包資源的過程中,會執行以下兩個額外的操作:
1、賦予每一個非assets資源一個ID值,這些ID值以常量的形式保存在R.java文件中。
2、生成一個resources.arsc文件,用來描述那些具有ID值的資源的配置信息,他的內容就相當於是一個資源索引表。
有了資源ID和索引表以后,android資源管理框架就可以迅速根據當前設備配置信息來定位最匹配的資源了。
============================================================
先理解這么多,至於aapt打包工具的工作流程就先不理解了。
