APK是Android Package的縮寫,即Android安裝包(apk)。通過將APK文件直接傳到Android模擬器或Android手機中執行即可安裝。APK文件基於 zip 文件格式,它與 jar 文件的構造方式相似。
1. APK包中有些什麼
文件名稱 | 文件類型 | 文件作用 |
---|---|---|
classes.dex | 文件 | java源文件經過編譯和轉換後生成的二進制的字節碼文件 |
resource.arsc | 文件 | 經過 aapt 編譯後的二進制的資源文件 |
AndroidManifest.xml | 文件 | 經過 aapt 編譯後的二進制的 xml 文件 |
res | 文件夾 | 除圖片和 res/raw 文件夾下的文件外,其餘的 xml 文件都被 aapt 編譯成二進制的 xml 文件 |
assets | 文件夾(可選) | 存放不進行編譯的原生文件,可以是一些圖片,或者是html、js、css文件 |
lib | 文件夾(可選) | 存放應用程序依賴的 native 庫文件,一般是用 c/c++ 編寫,如 so 文件 |
META-INF | 文件夾 | 存放簽名信息以及每一個文件的哈希值(BASE64) |
2. 打包用到的工具
工具名稱 | 功能介紹 | 在操作系統中的路徑 |
---|---|---|
aapt | Android資源打包工具 | ${ANDROID_SDK_HOME}/platform-tools/appt |
aidl | Android接口描述語言轉化爲.java文件的工具 | ${ANDROID_SDK_HOME}/platform-tools/aidl |
javac | Java Compiler | ${JDK_HOME}/javac 或 /usr/bin/javac |
dex | 轉化.class文件爲Davik VM能識別的.dex文件 | ${ANDROID_SDK_HOME}/platform-tools/dx |
apkbuilder | 生成apk包 | ${ANDROID_SDK_HOME}/tools/opkbuilder |
jarsigner | .jar文件的簽名工具 | ${JDK_HOME}/jarsigner 或 /usr/bin/jarsigner |
zipalign | 字節碼對齊工具 | ${ANDROID_SDK_HOME}/tools/zipalign |
3. 打包的具體過程
上圖顯示的是APK打包的流程圖。對於每一步具體的流程如下所示:
3.1 打包資源文件,生成相應的 R.java 文件
- 工具:aapt
- 輸入:res 文件夾,assets 文件夾,AndroidManifest.xml 文件
- 輸出:R.java,二進制的 resource.arsc ,res 文件夾(包括二進制的 xml 文件以及 沒有改變的圖片和 res/raw 下的文件),沒有改變的 assets 文件夾,二進制的 AndroidManifest.xml 文件
1 . R.java
R.java
中有擁有大量的靜態內部類,每當有這種資源添加時,就在R.java文件中添加一條靜態內部類裏的靜態常量類成員,且所有成員都是int類型。
2 . resources.arsc
resources.arsc
記錄了所有的應用程序資源目錄的信息,包括每一個資源名稱、類型、值、ID以及所配置的維度信息。其作用類似一個索引表,能夠快速指引並找到系統資源。
3.2 處理 AIDL 文件,生成相應的 java 文件
- 工具:aidl(Android Interface Denifition Language)
- 輸入:aidl文件
- 輸出:相應的 java 接口文件
3.3 編譯所有的 java 文件,生成 class 文件
通過Java Compiler編譯R.java、Java接口文件、Java源文件,生成.class文件。
- 工具:javac(java 編譯器)
- 輸入:R.java,java接口文件,java源文件
- 輸出:class文件
3.4 把class文件轉換成dex文件
通過dex命令,將.class文件和第三方庫中的.class文件處理生成classes.dex。
- 工具:dx.bat
- 輸入:class文件,第三方庫文件.jar(jar包中大都是class文件)
- 輸出:classes.dex文件
3.5 打包生成apk文件
將classes.dex、resources.arsc、res文件夾(res/raw資源被原裝不動地打包進APK之外,其它的資源都會被編譯或者處理)、Other Resources(assets文件夾)、AndroidManifest.xml打包成apk文件。
- 工具:apkbuilder
- 輸入:resource.arsc文件,AndroidManifest.xml文件,res文件夾,assets文件夾,classes.dex文件
- 輸出:apk文件
res/raw和assets的相同點與不同點:
相同點 | 不同點 |
---|---|
兩者目錄下的文件在打包後會原封不動的保存在apk包中,不會被編譯成二進制。 | 1.res/raw中的文件會被映射到R.java文件中,訪問的時候直接使用資源ID即R.id.filename;assets文件夾下的文件不會被映射到R.java中,訪問的時候需要AssetManager類。2.res/raw不可以有目錄結構,而assets則可以有目錄結構。 |
3.6 對apk文件進行簽名
對apk進行簽名,可以進行Debug和Release 簽名。
- 工具:apksigner
- 輸入:未簽名的apk文件
- 輸出:簽名的apk文件
3.7 對簽名後的apk文件進行對齊處理
工具:zipalign
輸入:簽名的apk文件
輸出:最終的apk文件
注:如果是release版本,需要對apk文件進行對齊處理。對齊處理使得apk包中的所有資源文件距離文件起始偏移爲4字節整數倍,這樣通過內存映射訪問apk文件時的速度更快,同時減少運行時內存的使用。