Android Studio的build發(fā)生了什么?

最近和一個(gè)iOS同學(xué)說(shuō),我們Android apk build要比ios慢很多,他問(wèn)我為什么要這么久,把我問(wèn)懵了,不知道怎么解釋。其實(shí)很多時(shí)候,你只要比別人多想一步就很厲害了。多問(wèn)問(wèn)自己為什么。

我們先看一張官方文檔提供的apk構(gòu)建流程圖


https://developer.android.google.cn/studio/build/

從上圖可以看出來(lái),構(gòu)建的過(guò)程主要分為兩步:

  • 編譯源碼、資源以及第三方依賴庫(kù)
  • 簽名、打包,生成apk

下面再來(lái)看另外一張圖,詳細(xì)分析了apk的構(gòu)建過(guò)程以及構(gòu)建過(guò)程中的工具


圖片出處參考水印

流程概述:

  1. 打包資源文件,生成R.java文件
  2. 處理aidl文件,生成對(duì)應(yīng)的java文件
  3. 編譯工程源文件,生成相應(yīng)的class文件
  4. 轉(zhuǎn)換剛剛生成的class文件以及第三方依賴的class文件,生成dex文件
  5. 打包生成apk
  6. 對(duì)apk進(jìn)行簽名,生成簽名之后的apk
  7. 對(duì)生成的apk進(jìn)行優(yōu)化,生成簽名+優(yōu)化后的apk

打包過(guò)程中需要的工具

aapt
Android資源打包工具,
目錄:${ANDROID_SDK_HOME} /build-tools/ANDROID_VERSION/aapt

aidl
將aidl文件轉(zhuǎn)成java文件
目錄:${ANDROID_SDK_HOME}/build-tools/ ANDROID_VERSION/aidl

javac
不用解釋了吧
目錄:${JDK_HOME}

dex
將class文件轉(zhuǎn)成Dalvik虛擬機(jī)能識(shí)別的dex文件
目錄:${ANDROID_SDK_HOME}/build-tools/ ANDROID_VERSION/dx

apkbuilder
打包生成apk
這里需要注意下,就是這個(gè)工具已經(jīng)在2014年就已經(jīng)被移除了,在sdk的build-tools目錄下根本就么有這個(gè)命令?,F(xiàn)在打包生成apk用的是${ANDROID_SDK_HOME}/tools/lib/sdk-xxx.jar中的ApkBuilderMain類。

Jarsigner
簽名工具,目錄在${JDK_HOME}

zipaling
對(duì)apk進(jìn)行優(yōu)化減少其在設(shè)備上運(yùn)行時(shí)的內(nèi)存占用。
目錄:${ANDROID_SDK_HOME}/build-tools/ ANDROID_VERSION/zipalign

構(gòu)建流程詳細(xì)分析

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

這一步主要用的是aapt工具,打包的資源文件主要分為三部分,

  • res目錄,包括圖片、xml等
  • AndroidManifest.xml
  • Assets文件
  • Android.jar
    上面這些資源文件中的xml(除了assets和raw目錄)基本都會(huì)被編譯成二進(jìn)制的xml文件,這樣空間更小。
    經(jīng)過(guò)aapt之后,主要生成兩個(gè)文件,R.java文件以及resources.arsc文件。
    R.java主要存放的是資源id,在我們公司的組件化過(guò)程中,為了防止插件和主站之間的資源id沖突,就是通過(guò)修改aapt源碼來(lái)生成不同id,確保資源id不會(huì)沖突。
    resources.arsc,存放了資源id與路徑之間的映射關(guān)系。

關(guān)于資源打包的詳細(xì)過(guò)程,可以參考老羅的博客https://blog.csdn.net/luoshengyang/article/details/8744683

這里插播一條res/rawassets目錄的區(qū)別

  • 兩個(gè)目錄下的資源都直接拷貝到apk包中,不會(huì)編譯成二級(jí)制文件
  • raw目錄下的文件會(huì)被映射到R.java文件中,可以通過(guò)R.id.xx來(lái)訪問(wèn),而assets目錄文件只能通過(guò)AssetManager來(lái)訪問(wèn)
  • assets目錄下可以創(chuàng)建目錄,而raw目錄不行

解析AIDL文件生成對(duì)應(yīng)的java文件
使用aidl工具生成AIDL.java文件,這個(gè)很簡(jiǎn)單,應(yīng)該就是通過(guò)一個(gè)模板文件了

java文件編譯成class
使用javac工具來(lái)編譯java文件為class文件了
編譯后可對(duì)代碼進(jìn)行混淆處理,主要包括刪除無(wú)用類、字節(jié)碼優(yōu)化、重命名等操作,只需在build.gradle中配置混淆規(guī)則即可

class轉(zhuǎn)dex
這里主要使用dx來(lái)講java字節(jié)碼轉(zhuǎn)成Dalvik字節(jié)碼

打包apk
調(diào)用ApkBuilderMain這個(gè)java類來(lái)打包資源以及dex文件和so文件等

簽名
對(duì)apk進(jìn)行簽名

優(yōu)化并生成apk
使用zipalign來(lái)優(yōu)化,具體怎么優(yōu)化,可以參考https://developer.android.com/studio/command-line/zipalign

參考文章:
https://blog.csdn.net/jason0539/article/details/44917745

最后編輯于
?著作權(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)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,000評(píng)論 2 59
  • Android插件化基礎(chǔ)的主要內(nèi)容包括 Android插件化基礎(chǔ)1-----加載SD上APKAndroid插件化基...
    隔壁老李頭閱讀 7,392評(píng)論 13 48
  • 1.介紹 如果你正在查閱build.gradle文件的所有可選項(xiàng),請(qǐng)點(diǎn)擊這里進(jìn)行查閱:DSL參考 1.1新構(gòu)建系統(tǒng)...
    Chuckiefan閱讀 12,365評(píng)論 8 72
  • 夢(mèng)里不知身是客,苒苒已惘然。 簾外聽(tīng)夏聲,風(fēng)也飄飄,雨又瀟瀟。 別時(shí)不易見(jiàn)更難,佳人望西山。 天地雙只影,嘆老...
    折落的時(shí)光閱讀 433評(píng)論 0 0

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