Android-apk編譯打包流程


典型Android應(yīng)用模塊的構(gòu)建流程通常按照一下步驟執(zhí)行:

編譯器會(huì)將源代碼轉(zhuǎn)換成 DEX 文件(Dalvik可執(zhí)行文件,其中包括在 Android 設(shè)備上運(yùn)行的字節(jié)碼),并將其他所有內(nèi)容轉(zhuǎn)換成編譯后的資源

APK 打包器將 DEX 文件和編譯后的資源合并到一個(gè) APK 中。不過(guò),在將應(yīng)用安裝并部署到 Android 設(shè)備之前,必須先為 APK 簽名

APK 打包器使用調(diào)試或發(fā)布密鑰庫(kù)為 APK 簽名:

如果您構(gòu)建的是調(diào)試版應(yīng)用(即專(zhuān)用于測(cè)試和分析的應(yīng)用),則打包器會(huì)使用調(diào)試密鑰庫(kù)作為應(yīng)用簽名。Android Studio 會(huì)自動(dòng)使用調(diào)試密鑰庫(kù)配置新項(xiàng)目

如果您構(gòu)建的是打算對(duì)外發(fā)布的發(fā)布版應(yīng)用,則打包器會(huì)使用發(fā)布密鑰庫(kù)作為應(yīng)用簽名。要?jiǎng)?chuàng)建發(fā)布密鑰庫(kù),請(qǐng)參閱?在 Android Studio 中為應(yīng)用簽名

在生成最終 APK 之前,打包器會(huì)使用?zipalign?工具對(duì)應(yīng)用進(jìn)行優(yōu)化,以減少其在設(shè)備上運(yùn)行時(shí)占用的內(nèi)存。

構(gòu)建流程結(jié)束時(shí),您將獲得應(yīng)用的調(diào)試版 APK 或發(fā)布版 APK,以用于部署、測(cè)試或發(fā)布給外部用戶(hù)。


下面是比較詳細(xì)的構(gòu)建流程:


Android APK 編譯打包流程

橢圓形部分是編譯打包過(guò)程中所需使用的工具(tools)

長(zhǎng)方形部分是Android應(yīng)用程序的各種資源文件

首先看中間的部分:

1、第一步:Java Compiler(java編譯器)把java代碼編譯成.class文件。

java代碼有三個(gè)部分:R.java、Application Source Code、JavaInterfaces

R.java:由aapt工具生成,aapt后面介紹

Application Source Code

JavaInterfaces: (如果有.aidl文件的話(huà))aidl工具會(huì)將.aidl files生成java接口文件。

注:AIDL是Android Interface Definition Language的縮寫(xiě),是Android跨進(jìn)程通訊的一種方式,該階段會(huì)檢索Project中所有的aidl文件,并轉(zhuǎn)換為對(duì)應(yīng)的Java文件。

2、第二步:dex工具把.class文件 + 3rd Party Libraries文件生成Delvik可執(zhí)行的.dex文件

3rd Party Libraries文件:依賴(lài)的第三方庫(kù)

在此過(guò)程中,dex工具不僅會(huì)把java字節(jié)碼轉(zhuǎn)化為Delvik字節(jié)碼,還會(huì)壓縮常量池,消除冗余信息等

3、第三步:apkbuilder工具將Compiled Resources + .dex files + Other Resources生成 .apk 文件

Compiled Resources:由aapt工具生成

Other Resources:

4、第四步:Jarsigner工具使用Debug or Release Keystore對(duì) .apk 文件進(jìn)行打包

5、第五步:zipalign工具將Signed .apk(已簽名apk)進(jìn)行對(duì)齊(優(yōu)化簽名包),生成最終的 .apk 文件


0、這個(gè)算是第零步:

aapt(Android Asset Packaging Tool,即Android資源打包工具)

aapt工具會(huì)根據(jù)res下面的資源和AndroidManifest.xml生成一個(gè)資源索引文件(resource.arsc,其中包含了各個(gè)資源文件的映射, 可以理解為索引, 通過(guò)該文件能找到對(duì)應(yīng)的資源文件信息。)和一個(gè)R.java文件。

assets下面的資源不編譯,直接壓縮到apk中。


總結(jié)下來(lái),整個(gè)過(guò)程就是:

編譯 -》dex -》打包 -》簽名和對(duì)齊


面試關(guān)于apk打包的問(wèn)題:

1、apk編譯打包流程

2、為什么要用aapt把xml文件編譯成二進(jìn)制文件?

首先二進(jìn)制格式的XML文件占用空間更小。因?yàn)樗械腦ML元素的標(biāo)簽、屬性名稱(chēng)、屬性值和內(nèi)容所涉及到的字符串都會(huì)被統(tǒng)一收集到一個(gè)字符串資源池中去,并且會(huì)去重。有了這個(gè)字符串資源池,原來(lái)使用字符串的地方就會(huì)被替換成一個(gè)索引字符串資源池的整數(shù)值,從而可以減少文件的大小

其次是二進(jìn)制的XML文件解析速度更快,這是由于二進(jìn)制的XML元素里面不再包含有字符串值,因此可以避免了進(jìn)行字符串解析,從而提高速度。

3、Dex打包關(guān)于65536的問(wèn)題

這個(gè)問(wèn)題是由于DEX文件格式限制,一個(gè)DEX文件中的method個(gè)數(shù)使用原生類(lèi)型short來(lái)索引文件的方法,也就是4個(gè)字節(jié)共計(jì)最多表達(dá)65536個(gè)method,field/class個(gè)數(shù)也均有此限制,對(duì)于DEX文件,則是將工程所需要全部class文件合并壓縮到一個(gè)DEX文件期間,也就是Android打包的DEX過(guò)程中,單個(gè)DEX文件可被引用的方法總數(shù)(自己開(kāi)發(fā)的代碼以及所引用的Android框架、類(lèi)庫(kù)的代碼)被限制為66536。

4、打包流程中最后一步,為什么要對(duì)齊?

對(duì)齊是為了加快資源的訪(fǎng)問(wèn)速度。如果每個(gè)資源的開(kāi)始位置上都是一個(gè)資源之后的4n字節(jié),那么訪(fǎng)問(wèn)下一個(gè)資源就不用遍歷,直接跳到4字節(jié)處判斷是不是一個(gè)新的資源即可。有點(diǎn)類(lèi)似于資源數(shù)組化,數(shù)組的訪(fǎng)問(wèn)速度當(dāng)然比鏈表快

5、Android是怎么通過(guò)R文件找到真正的資源文件?

aapt工具對(duì)每個(gè)資源文件都生成了唯一的ID,這些ID保存在R.java文件中。資源ID是一個(gè)4字節(jié)的的無(wú)符號(hào)證書(shū),在R.java文件中用16進(jìn)制表示。其中,最高的1字節(jié)表示Package ID,次高1個(gè)字節(jié)表示Type ID,最低2字節(jié)表示Entry ID。只有一個(gè)ID 如何能引用到實(shí)際資源?實(shí)際上aapt工具還生成一個(gè)文件resources.arsc,相當(dāng)于一個(gè)資源索引表,或者你理解成一個(gè)map也行,map的key是資源ID,value是資源在apk文件中的路徑。resource.arsc里面還有其他信息,這里就不多說(shuō)了。通過(guò)resource.arsc配合,就能引用到實(shí)際的資源文件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容