Android 打包流程詳解

Android 打包流程詳解(待寫)

序言

每次點擊一下Android Studio上的運行以后,就默默的等待程序運行起來。有時候出現問題百度一下,然后修修改改運行起來就可以了。但是作為一個安卓開發(fā)人員,我們應該去深層次的去理解apk的打包流程以及打包中是如何去做處理的。否則的話,什么構建優(yōu)化,什么插樁技術,什么hook,一切都是免談的。就像我們之前的一篇Android的inflate源碼詳解中,就涉及到了通過AssetManager類調用Native方法完成對 resources.arsc 文件的解析。當時我們也沒有進行深入的探究這個 resources.arsc 里面到底有什么?又是如何生成的?。那么今天我們就把這部分的知識也都整理一下。

匯總圖

我們先上一張apk的最詳細的打包流程圖。

  1. 打包資源文件,生成R.java文件
  2. 處理aidl文件,生成Java文件
  3. 將項目源代碼編譯生成class文件
  4. 將所有的calss文件,生成classes.dex文件
  5. 打包生成APK文件
  6. 對APK進行簽名
  7. 對簽名之后的APK文件進行對其處理。

各階段分析

整體的流程圖就是這樣了,聽著很簡單。但是其實每一步都有很多東西需要我們去處理的。而且有時候我們的一些技術可以應用到這些打包的過程中。

打包資源文件,生成R.java文件

使用aapt命令來打包AndroidManifest.xml文件和其他資源文件,生成R.java、Resources.arsc和res文件。

具體流程:

編譯res和assets目錄下的資源并生成resources.arsc文件,resources.arsc文件包含了資源的ID信息

調用ResourceTable.cpp文件中的parseAndAddEntry方法根據ID信息生成R.java文件。

對res目錄下的xml文件進行編譯,這樣處理過的xml文件就被簡單“加密”了

生成的文件:
  • res目錄。這里生成的res文件都是轉化為二進制xml文件的
    • 包括了animator
    • anim
    • color
    • drawable里面的xml文件
    • layout布局文件
    • menu菜單布局文件
    • values文件
    • xml應用配置文件
  • R.java文件
    • R.java文件包含了編寫代碼時候用的資源的ID值。
  • resources.arsc文件
    • resources.arsc這個文件記錄了所有的應用程序資源目錄的信息,包括每一個資源名稱、類型、值、ID以及所配置的維度信息。是一個資源索引表,在給定資源ID和設備配置信息的情況下能快速找到資源。

知識點:

  1. 這一步里面處理的資源,在應用層都是通過ID來進行訪問的在【Android的inflate源碼詳解】中,我們獲取布局就是使用的資源id。
  2. xml之所以編譯成二進制,是因為里面都是各種字符,不利于快速遍歷。編譯成二進制文件,用數字替換各種符號,一方面能快速訪問,另一方面也能減少大小。
  3. 有時候我們的布局文件寫錯了,程序報無法找到R文件的原因也可以理解了,因為這一步資源文件有問題,文件ID生成失敗,肯定就沒辦法找到R文件了。
  4. apk運行時會根據設備的不同屬性(如屏幕密度)尋址,resource.arsc就是通過相同的ID,根據不同的配置索引找到最佳資源
  5. aapt打包走的是單線程、流水式任務從上到下構建。所以代碼量越多,資源量越多,構建過程越慢

處理aidl,生成Java文件

aidl(Android Interface Definition Language,Android接口描述語言),位于android-sdk/platform-tools目錄下。aidl工具解析接口定義文件然后生成相應的Java代碼接口供程序調用。如果項目沒用到aidl則跳過這一步。

aidl文件很多時候都是跨進行來使用的。

編譯項目源代碼,生成class文件

Java Compiler階段。項目中所有的Java代碼,R.java和.aidl生成的文件,都會通過Java編譯器(javac)編譯成.class文件,生成的class文件位于工程中的bin/classes目錄下。

這個地方是我們能夠進行操作的地方,在AOP切面編程中,可以使用Aspect技術來實現對于通用邏輯的處理。比如點擊事件、日志打印等。

將所有的class文件,生成classes.dex文件

這里會將我們工程中生成的class以及第三方的class文件通過dx工具生成classess.dex文件,因為我們的dex文件會有65535的方法數的限制,所以如果方法數超過了,會打包成多個dex文件。

dx工具主要工作是將Java字節(jié)碼轉成Dalvik字節(jié)碼、壓縮常量池、消除冗余信息等。

打包生成APK文件

所有沒有編譯的資源(如images、assets目錄下的資源);編譯過的資源(resources.arsc以及二進制xml文件)、.dex文件通過apkbuilder工具打包到最終的.apk文件中。

對于未編譯過的文件,打包時會直接打包到APP中,對于這一類資源的訪問,應用層代碼需要通過文件名對其進行訪問。

調用流程:

先以resources.arsc文件為基礎生成一個apk

調用ApkBuilderMain.java中的addSourceFolder方法添加工程資源,處理包括res和assets目錄中的文件,添加完資源后調用addResourceFromJar方法往apk中寫入依賴庫

調用addNativeLibraries方法添加工程libs目錄下的nativey庫

調用sealApk關閉Apk文件。

只是點:

  1. 3.0之前用apkbuilder腳本,3.0之后用
  2. apkbuilder腳本也是調用的sdklib的ApkBuilderMain.java類

對APK進行簽名

apk生成以后,必須要進行簽名才可以被安裝。在開發(fā)過程中使用的是debug.keystore。

簽名后的APK文件對其

通過zipalign進行文件的對其操作。對其的過程是將apk包中的所有資源文件距離文件起始偏移調整為4字節(jié)的整數倍。內存對于硬件文件的讀取是按照4字節(jié)的整數倍來進行讀取的,這樣調整以后,內存訪問apk的資源文件時,就可以整頁的讀取,從而減少運行時內存的使用。如果每個資源的開始位置都是上一個資源之后的 4*n字節(jié),那么訪問下一個資源就不用遍歷,直接跳到4*n字節(jié)處判斷是不是一個新的資源即可。

本文由 開了肯 發(fā)布!

同步公眾號[開了肯]

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容