Apk打包-編譯和打包過程


參考:http://www.jianshu.com/p/7c288a17cda8

 

1.概況

  • Android APK是如何來的呢?
    懷着這個問題去查資料,發現了下邊這張圖。

 
  • 由android的項目經過編譯和打包,形成了:

    1. .dex 文件
    2. resources.arsc
    3. uncompiled resources
    4. AndroidManifest.xml

    解壓了一個普通的apk文件,解壓出來的文件如下:


     


    classes.dex 是.dex文件。
    resources.arsc是resources resources文件。
    AndroidManifest.xml是AndroidManifest.xml文件。
    res是uncompiled resources。
    META-INF是簽名文件夾。

  • META-INF其中有三個文件:


     


    MANIFEST.MF文件
    版本號以及每一個文件的哈希值(BASE64)。包括資源文件。這個是對每個文件的整體進行SHA1(hash)。

    Manifest-Version: 1.0
    Built-By: Generated-by-ADT
    Created-By: Android Gradle 2.2.0
    Name: res/drawable-xhdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png
    SHA1-Digest: I9s6aQ5VyOLrNo4odqSij549Oyo=
    Name: res/drawable-mdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png
    SHA1-Digest: D6dilO+UMcglambujyMOhNbLZuY=
    ……

    CERT.SF
    這個是對每個文件的頭3行進行SHA1 hash。

    Signature-Version: 1.0
    X-Android-APK-Signed: 2
    SHA1-Digest-Manifest: QxOfCCAuQtZnHh0YRNnoxmiHT80=
    Created-By: 1.0 (Android)
    Name: res/drawable-xhdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png
    SHA1-Digest: I9s6aQ5VyOLrNo4odqSij549Oyo=
    Name: res/drawable-mdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png
    SHA1-Digest: D6dilO+UMcglambujyMOhNbLZuY=
    ……

    CERT.RSA
    這個文件保存了簽名和公鑰證書。

2. 具體打包過程


 
打包過程使用的工具
 
名稱
功能介紹 在操作系統中的路徑 源碼路徑
aapt
(Android Asset Package Tool)
Android資源打包工具
${ANDROID_SDK_HOME} /build-tools/
 ANDROID_VERSION/aapt
frameworks\base\tools\aap
aidl
(android interface definition language)

Android接口描述語言,

將aidl轉化為.java文件的工具

${ANDROID_SDK_HOME}/build-tools/
 ANDROID_VERSION/aidl
frameworks\base\tools\aidl
javac Java Compiler

${JDK_HOME}/java

c或/usr/bin/javac

 
dex
轉化.class文件為Davik VM
能識別的.dex文件
${ANDROID_SDK_HOME}/build-tools/
 ANDROID_VERSION/dx
 
apkbuilder
生成apk包
${ANDROID_SDK_HOME}/tools/
 apkbuilder
sdk\sdkmanager\libs\sdklib\
 src\com\android\sdklib\build\
 ApkBuilderMain.java
jarsigner .jar文件的簽名工具 ${JDK_HOME}/jarsigner或/usr/bin/jarsigner
 
zipalign 字節碼對齊工具

${ANDROID_SDK_HOME}/tools

 /zipalign

 
 

2.1 aapt階段

  • 使用aapt來打包res資源文件,生成R.java、resources.arsc和res文件(二進制 & 非二進制如res/raw和pic保持原樣)

  • res目錄有9種目錄
    --animator。這類資源以XML文件保存在res/animator目錄下,用來描述屬性動畫。
    --anim。這類資源以XML文件保存在res/anim目錄下,用來描述補間動畫。
    --color。這類資源以XML文件保存在res/color目錄下,用描述對象顏色狀態選擇子。
    --drawable。這類資源以XML或者Bitmap文件保存在res/drawable目錄下,用來描述可繪制對象。例如,我們可以在里面放置一些圖片(.png, .9.png, .jpg, .gif),來作為程序界面視圖的背景圖。注意,保存在這個目錄中的Bitmap文件在打包的過程中,可能會被優化的。例如,一個不需要多於256色的真彩色PNG文件可能會被轉換成一個只有8位調色板的PNG面板,這樣就可以無損地壓縮圖片,以減少圖片所占用的內存資源。
    --layout。這類資源以XML文件保存在res/layout目錄下,用來描述應用程序界面布局。
    --menu。這類資源以XML文件保存在res/menu目錄下,用來描述應用程序菜單。
    --raw。這類資源以任意格式的文件保存在res/raw目錄下,它們和assets類資源一樣,都是原裝不動地打包在apk文件中的,不過它們會被賦予資源ID,這樣我們就可以在程序中通過ID來訪問它們。例如,假設在res/raw目錄下有一個名稱為filename的文件,並且它在編譯的過程,被賦予的資源ID為R.raw.filename,那么就可以使用以下代碼來訪問它:

    Resources res = getResources();  
    InputStream is = res .openRawResource(R.raw.filename);

    --values。這類資源以XML文件保存在res/values目錄下,用來描述一些簡單值,例如,數組、顏色、尺寸、字符串和樣式值等,一般來說,這六種不同的值分別保存在名稱為arrays.xml、colors.xml、dimens.xml、strings.xml和styles.xml文件中。
    --xml。這類資源以XML文件保存在res/xml目錄下,一般就是用來描述應用程序的配置信息。

  • R.java文件


     


    這就是R.java的源代碼,里面擁有很多個靜態內部類,比如layout,string等。
    每當有這種資源添加時,就在R.java文件中添加一條靜態內部類里的靜態常量類成員,且所有成員都是int類型。


     


    里面的資源可以有兩種方法引用:
    1.在java程序中引用資源按照java的語法來引用即:R.resource_type.resource_
    name注意:resource_name不需要文件的后綴名
    2.在XML文件中引用資源格式:@[package:]type/name

  • resources.arsc文件
    resources.arsc這個文件記錄了所有的應用程序資源目錄的信息,包括每一個資源名稱、類型、值、ID以及所配置的維度信息。我們可以將這個resources.arsc文件想象成是一個資源索引表,這個資源索引表在給定資源ID和設備配置信息的情況下,能夠在應用程序的資源目錄中快速地找到最匹配的資源。

2.2 aidl階段

  • AIDL (Android Interface Definition Language), Android接口定義語言,Android提供的IPC (Inter Process Communication,進程間通信)的一種獨特實現。
    這個階段處理.aidl文件,生成對應的Java接口文件。

2.3 Java Compiler階段

  • 通過Java Compiler編譯R.java、Java接口文件、Java源文件,生成.class文件。

2.4 dex階段

  • 通過dex命令,將.class文件和第三方庫中的.class文件處理生成classes.dex。

2.5 apkbuilder階段

  • 將classes.dex、resources.arsc、res文件夾(res/raw資源被原裝不動地打包進APK之外,其它的資源都會被編譯或者處理)、Other Resources(assets文件夾)、AndroidManifest.xml打包成apk文件。
    注意
    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則可以有目錄結構,也就是assets目錄下可以再建立文件夾

2.6 Jarsigner階段

  • 對apk進行簽名,可以進行Debug和Release 簽名。

2.7 zipalign階段

  • release mode 下使用 aipalign進行align,即對簽名后的apk進行對齊處理。
    Zipalign是一個android平台上整理APK文件的工具,它對apk中未壓縮的數據進行4字節對齊,對齊后就可以使用mmap函數讀取文件,可以像讀取內存一樣對普通文件進行操作。如果沒有4字節對齊,就必須顯式的讀取,這樣比較緩慢並且會耗費額外的內存。
    在 Android SDK 中包含一個名為 “zipalign” 的工具,它能夠對打包后的 app 進行優化。 其位於 SDK 的 build-tools 目錄下, 例如: D:\Develop\Android\sdk\build-tools\23.0.2\zipalign.exe
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM