當(dāng)前位置:首頁(yè) > IT技術(shù) > 移動(dòng)平臺(tái) > 正文

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程
2021-09-24 14:55:04

??Android Gradle Plugin??,簡(jiǎn)稱(chēng) AGP,老早之前就想好好研究下Android APK的打包過(guò)程,畢竟 ??APK包體積優(yōu)化?? 的前置知識(shí)之一。

奈何當(dāng)時(shí)的知識(shí)儲(chǔ)備嚴(yán)重不足,硬啃著實(shí)難受,在學(xué)了兩周的Gradle后 ,覺(jué)得應(yīng)該有 一戰(zhàn)之力 了,所以這一節(jié)來(lái)了!

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java

內(nèi)容較多,建議先收藏,有時(shí)間再慢慢細(xì)品~

0x1、網(wǎng)上流傳的三張APK打包流程圖

??Android官網(wǎng)?? 有一張新的打包流程圖(左),相比起舊的流程圖(右)更抽象,隱藏了很多細(xì)節(jié):

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_02

在 ??Android Studio Project Site?? 還找到了一張更詳細(xì)的圖:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_03

如果只是滿足于一個(gè)寫(xiě)基礎(chǔ)業(yè)務(wù)的Android開(kāi)發(fā)仔,了解下足矣,不過(guò)如果想有更深的造詣,還是建議往下學(xué)的。

比如面試時(shí)(我自己腦補(bǔ)的~):

  • 面試官:簡(jiǎn)歷上寫(xiě)的做過(guò)APK體積優(yōu)化?說(shuō)說(shuō)都做了哪方面的優(yōu)化:
  • 你:從資源大頭入手,把png圖片都轉(zhuǎn)成webp,使用AndResGuard對(duì)資源進(jìn)行混淆;
  • 面試官:用Gradle寫(xiě)一個(gè)webp轉(zhuǎn)換插件,說(shuō)下思路;
  • 你:不會(huì),我一般右鍵直接轉(zhuǎn)換…
  • 面試官:那說(shuō)下AndResGuard的大概原理;
  • 你:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_04

本節(jié)就來(lái)了解下AGP的構(gòu)建過(guò)程,以及簡(jiǎn)單了解下APK的打包過(guò)程~

Tips:Tasks那么多,不可能一個(gè)個(gè)去精讀源碼解析,不同插件版本還有差異,不如授之以漁,本文的目的就是讓讀者遇到問(wèn)題時(shí)懂得如何追根溯源,找到對(duì)應(yīng)的源碼。



0x2、如何查看插件源碼

研究對(duì)象是AGP的源碼,所以要先搞一份源碼,方法有下述幾種:

1. 下載完整源碼

如果磁盤(pán)空間比較充足,可以通過(guò)repo的方式,將Android Gradle Plugin的源碼下載到本地(貌似30多G):

# 最新源碼的只有3.4.0的
repo init -u https://android.googlesource.com/platform/manifest -b gradle_3.4.0
repo sync

2. 下載部分源碼

當(dāng)然不需要編譯的話,可以直接下對(duì)應(yīng)源碼包,來(lái)到下述地址:??build-system??

點(diǎn)tgz下載:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_05

然后用VS Code之類(lèi)的代碼查看工具查看即可~

3. 取巧(推薦)

在app層級(jí)的build.gradle添加下述依賴(lài):

implementation 'com.android.tools.build:gradle:3.4.0'

build下,然后在左側(cè) ??External Libraries?? 即可找到源碼:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_06



0x3、閱讀源碼前的一些補(bǔ)充

閱讀源碼前建議溫習(xí)下我前面寫(xiě)的三篇文章,另外補(bǔ)充點(diǎn)姿勢(shì):

Gradle Plugin 中的Task主要有三種:??普通Task??、??增量Task??、??Transform??。

Task一般會(huì)繼承 ??DefaultTask?? 或 ??IncrementalTask??,而 ??@TaskAction?? 注解的方法,就是此Task做的事。

繼承 ??IncrementalTask?? 的類(lèi)為增量Task,這個(gè)增量是相對(duì)于全量來(lái)說(shuō)的,全量指的是:調(diào)用完clean后第一次編譯過(guò)程,修改代碼或資源后再次編譯,就是增量編譯。幾個(gè)關(guān)鍵方法:

public abstract class IncrementalTask extends BaseTask {
// 是否需要增量,默認(rèn)false
@Internal protected boolean isIncremental() { }

// 需要子類(lèi)實(shí)現(xiàn),全量時(shí)執(zhí)行的任務(wù)
protected abstract void doFullTaskAction() throws Exception;

// 增量時(shí)執(zhí)行的任務(wù),默認(rèn)什么都不執(zhí)行,參數(shù)是增量時(shí)修改過(guò)的文件
protected void doIncrementalTaskAction(Map<File, FileStatus> changedInputs) throws Exception{ }

@TaskAction
void taskAction(IncrementalTaskInputs inputs) throws Exception {
// 判斷是否是增量,是執(zhí)行doIncrementalTaskAction,否則執(zhí)行doFullTaskAction


// 獲取修改文件
private Map<File, FileStatus> getChangedInputs(IncrementalTaskInputs inputs) { }
}

至于 ??Transform??(變換),是Android官方提供給開(kāi)發(fā)者,在**.class → .dex轉(zhuǎn)換期間用來(lái)修改.class文件的一套API**,留意 ??transform()?? 方法的實(shí)現(xiàn)就好。



0x4、執(zhí)行g(shù)radle assemble的Task鏈

我們常常使用下面的命令來(lái)打包APK:

gradlew assemble

可以由此入手,看下打包一次都涉及到了哪些Task,鍵入下述命令(linux、mac使用./gradlew):

gradlew assemble --console=plain

輸出結(jié)果及要點(diǎn)簡(jiǎn)述如下所示:

:app:preBuild UP-TO-DATE    → 空task,錨點(diǎn)
:app:preDebugBuild → 空task,錨點(diǎn)
:app:compileDebugAidl NO-SOURCE → 處理AIDL
:app:checkDebugManifest → 檢查Manifest是否存在
:app:compileDebugRenderscript NO-SOURCE → 處理renderscript
:app:generateDebugBuildConfig → 生成 BuildConfig.java
:app:mainApkListPersistenceDebug → 生成 app-list.gson
:app:generateDebugResValues → 生成resvalue,generated.xml
:app:generateDebugResources → 空task,錨點(diǎn)
:app:mergeDebugResources → 合并資源文件
:app:createDebugCompatibleScreenManifests → manifest文件中生成compatible-screens,指定屏幕適配
:app:processDebugManifest → 合并manifest.xml文件
:app:processDebugResources → aapt打包資源
:app:compileDebugKotlin → 編譯Kotlin文件
:app:prepareLintJar UP-TO-DATE → 拷貝 lint jar包到指定位置
:app:generateDebugSources → 空task,錨點(diǎn)
:app:javaPreCompileDebug → 生成 annotationProcessors.json 文件
:app:compileDebugJavaWithJavac → 編譯 java文件
:app:compileDebugNdk → 編譯ndk
:app:compileDebugSources → 空task,錨點(diǎn)
:app:mergeDebugShaders → 合并 shader文件
:app:compileDebugShaders → 編譯 shaders
:app:generateDebugAssets → 空task,錨點(diǎn)
:app:mergeDebugAssets → 合并 assests文件
:app:validateSigningDebug → 驗(yàn)證簽名
:app:signingConfigWriterDebug → 編寫(xiě)SigningConfig信息
:app:checkDebugDuplicateClasses → 檢查重復(fù)class
:app:transformClassesWithDexBuilderForDebug → class打包成dex
:app:transformDexArchiveWithExternalLibsDexMergerForDebug → 打包第三方庫(kù)的dex
:app:transformDexArchiveWithDexMergerForDebug → 打包最終的dex
:app:mergeDebugJniLibFolders → 合并jni lib 文件
:app:transformNativeLibsWithMergeJniLibsForDebug → 合并jnilibs
:app:transformNativeLibsWithStripDebugSymbolForDebug → 去掉native lib里的debug符號(hào)
:app:processDebugJavaRes NO-SOURCE → 處理java res
:app:transformResourcesWithMergeJavaResForDebug → 合并java res
:app:packageDebug → 打包apk
:app:assembleDebug → 空task,錨點(diǎn)
:app:extractProguardFiles → 生成混淆文件

# 還會(huì)打一個(gè)release包,task和上述基本一致,此處省略~

當(dāng)然,也可以直接在 ??Build?? 窗口直接查看,雙擊右側(cè)Gradle窗口中assemble的Task,然后觀察此窗口:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_jvm_07

嘖嘖,還可以看到每個(gè)Task的執(zhí)行時(shí)間,不錯(cuò),但先不跟每個(gè)Task具體內(nèi)容,而是跟下AGP的構(gòu)建過(guò)程~

0x5、AGP的構(gòu)建過(guò)程

上一節(jié)將Gradle插件時(shí)說(shuō)過(guò),每個(gè)插件都會(huì)配置一個(gè) ??id名字.properties?? 的文件,在此寫(xiě)上插件的實(shí)現(xiàn)類(lèi),全局搜定位到下述文件:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_08

打開(kāi):

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_09

指向:??AppPlugin?? 類(lèi),跟下:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_10

上節(jié)說(shuō)過(guò):插件類(lèi)都繼承于 ??Plugin??,入口函數(shù) ??apply()??,但在這里沒(méi)找到,跟下:??AbstractAppPlugin?? → ??BasePlugin??。

① BasePlugin

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_11

行吧,在BasePlugin中重寫(xiě)了 ??apply()?? 方法,里面調(diào)用了兩個(gè)函數(shù),先跟下:??basePluginApply()?? 補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_12

執(zhí)行一些檢查操作,接著是 插件的初始化及配置,而另一個(gè)函數(shù):??pluginSpecificApply()?? 則是空實(shí)現(xiàn),接著跟下:配置項(xiàng)目、配置擴(kuò)展及創(chuàng)建Tasks的過(guò)程。

② configureProject() → 配置項(xiàng)目

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_13

創(chuàng)建DataBindingBuilder實(shí)例,強(qiáng)制使用不低于當(dāng)前所支持的最小插件版本,應(yīng)用Java插件,如果啟用了構(gòu)建緩存選項(xiàng),創(chuàng)建buildCache實(shí)例,添加了一個(gè)回調(diào):所有project執(zhí)行完后執(zhí)行資源回收相關(guān)操作。

③ configureExtension() → 配置DSL擴(kuò)展

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_14

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_15

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_16

完成下述幾項(xiàng)工作:

  • ① 創(chuàng)建build.gradle中的Android DSL;
  • ② 創(chuàng)建VariantFactory、TaskManager、VariantManager實(shí)例;
  • ③ 注冊(cè)新增/移除配置的回調(diào),包括:signingConfig,buildType,productFlavor;
  • ④ 創(chuàng)建默認(rèn)的debug簽名、debug和release兩種buildType;

④ createTasks() → 創(chuàng)建Tasks

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_17

跟下 ??createAndroidTask()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_18

跟下 ??createAndroidTasks()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_19

注意下:這里遍歷了所有的variantScope,然后調(diào)用 ??createTasksForVariantData()?? 創(chuàng)建變體數(shù)據(jù)對(duì)應(yīng)的Tasks:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_20

跟下:??createTasksForVariantScope()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_21

抽象方法,看下哪里實(shí)現(xiàn)了這個(gè)方法,搜下:??extends TaskManager??

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_22

最終定位到了:??ApplicationTaskManager?? 類(lèi)

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_23

噢吼,就是在這里完成APK打包過(guò)程的Tasks,可以簡(jiǎn)單跟跟驗(yàn)證下:??createAnchorTasks()??,創(chuàng)建錨點(diǎn)Tasks:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_24

跟下:??createVariantPreBuildTask()??

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_25

2333,跟上面的APK打包Task鏈的相呼應(yīng),AGP插件的構(gòu)建過(guò)程就跟到這里,接著了解下APK打包的Task。

0x6、Apk的打包過(guò)程

Tips:分享下搜索Task的實(shí)現(xiàn)類(lèi)的技巧 → 全局搜 “xxx”, “yyy” 即可快速定位對(duì)應(yīng)Task類(lèi),如 “compile”, “Aidl”,或者搜索整個(gè)Task,然后刪刪刪匹配。

1. compileDebugAidl

過(guò)程簡(jiǎn)述:??將.aidl文件通過(guò)aidl工具轉(zhuǎn)換成編譯器能夠處理的Java接口文件?? 相關(guān)代碼:AidlCompile.java → AidlProcessor.java → call()



2. checkDebugManifest

過(guò)程簡(jiǎn)述:??檢查AndroidManifest.xml文件是否存在?? 相關(guān)代碼:CheckManifest.java



3. compileDebugRenderscript

過(guò)程簡(jiǎn)述:??處理Renderscript文件(.rs)?? 相關(guān)代碼:RenderscriptCompile.java



4. generateDebugBuildConfig

過(guò)程簡(jiǎn)述:??生成 BuildConfig.java 文件?? 相關(guān)代碼:GenerateBuildConfig.java



5. mainApkListPersistenceDebug

過(guò)程簡(jiǎn)述:??持久化APK數(shù)據(jù)到apk-list.gson中?? 相關(guān)代碼:MainApkListPersistence.kt



6. generateDebugResValues

過(guò)程簡(jiǎn)述:??遍歷res下的values目錄下xml文件,生成resValues文件generated.xml?? 相關(guān)代碼:GenerateResValues.java → generate() → ResValueGenerator.java



7. mergeDebugResources

過(guò)程簡(jiǎn)述:??使用AAPT2合并資源文件?? 相關(guān)代碼:MergeResources.doFullTaskAction() → ResourceMerger.mergeData() → MergedResourceWriter.end() → mResourceCompiler.submitCompile() → AaptV2CommandBuilder.makeCompileCommand()

核心源碼解析:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_26

實(shí)現(xiàn)了isIncremental()方法,返回true,說(shuō)明支持增量編譯,跟下全量編譯方法 ??doFullTaskAction()??

ResourcePreprocessor preprocessor = getPreprocessor();
List<ResourceSet> resourceSets = getConfiguredResourceSets(preprocessor)

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_jvm_27

接著往下走:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_28

繼續(xù):

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_29

點(diǎn)進(jìn)merger.mergeData() → ResourceMerger.mergeData() → DataMerger.mergeData()

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_jvm_30

嘔吼,實(shí)際上調(diào)用的還是 ??MergedResourceWriter?? 類(lèi)里的方法,跟下addItem():

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_31

不同文件會(huì)創(chuàng)建對(duì)應(yīng)的 ??CompileResourceRequest?? 實(shí)例,并添加到 ??mCompileResourceRequests?? 中,后者是一個(gè)ConcurrentLinkedQueue隊(duì)列,資源最后會(huì)在end()方法處處理:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_32

最終調(diào)用 ??AaptV2CommandBuilder.makeCompileCommand()?? 方法生成aapt2命令去處理資源。

Tips:將圖片轉(zhuǎn)為webp格式的插件一般在此Task前處理~



8. createDebugCompatibleScreenManifests

過(guò)程簡(jiǎn)述:??manifest文件中生成compatible-screens,用于屏幕適配?? 相關(guān)代碼:CompatibleScreensManifest.kt



9. processDebugManifest

過(guò)程簡(jiǎn)述:??合并AndroidManifest.xml文件?? 相關(guān)代碼:ProcessApplicationManifest.java、ProcessLibraryManifest.java



10. processDebugResources

過(guò)程簡(jiǎn)述:??調(diào)用aapt2 link 打包資源并生成R.java文件?? 相關(guān)代碼:TaskManager.java → createProcessResTask()



11. compileDebugKotlin

過(guò)程簡(jiǎn)述:??編譯Kotlin文件為字節(jié)碼?? 相關(guān)代碼:沒(méi)找到…可能在kotlin插件源碼里



12. prepareLintJar

過(guò)程簡(jiǎn)述:??拷貝lint jar包到指定位置?? 相關(guān)代碼:PrepareLintJar.java



13. avaPreCompileDebug

過(guò)程簡(jiǎn)述:??生成annotationProcessors.json文件?? 相關(guān)代碼:JavaPreCompileTask.java



14. ompileDebugJavaWithJavac

過(guò)程簡(jiǎn)述:??編譯java文件?? 相關(guān)代碼:AndroidJavaCompile.java



15. compileDebugNdk

過(guò)程簡(jiǎn)述:??編譯NDK?? 相關(guān)代碼:NdkCompile.java



15. mergeDebugShaders

過(guò)程簡(jiǎn)述:??合并Renderscript文件(.rs)?? 相關(guān)代碼:MergeSourceSetFolders.java



16. compileDebugShaders

過(guò)程簡(jiǎn)述:??編譯Renderscript文件(.rs)?? 相關(guān)代碼:ShaderCompile.java



17. mergeDebugAssets

過(guò)程簡(jiǎn)述:??合并assets文件?? 相關(guān)代碼:MergeSourceSetFolders.java



18. validateSigningDebug

過(guò)程簡(jiǎn)述:??驗(yàn)證簽名?? 相關(guān)代碼:ValidateSigningTask.kt 附加信息:檢查當(dāng)前Variant的簽名配置中是否存在密鑰庫(kù)文件,如果當(dāng)前密鑰庫(kù)默認(rèn)為debug keystore,那密鑰庫(kù)不存在也會(huì)進(jìn)行相應(yīng)的創(chuàng)建。



19. signingConfigWriterDebug

過(guò)程簡(jiǎn)述:??編寫(xiě)SigningConfig信息?? 相關(guān)代碼:SigningConfigWriterTask.kt



20. checkDebugDuplicateClasses

過(guò)程簡(jiǎn)述:??檢查重復(fù)class?? 相關(guān)代碼:CheckDuplicateClassesTask.kt 附加信息:檢查項(xiàng)目外部依賴(lài)是否不包含重復(fù)類(lèi),打包成dex的時(shí)候再檢測(cè)報(bào)錯(cuò)不怎么友好,所以引入了這個(gè)Task用于快速失敗。



21. transformClassesWithDexBuilderForDebug

過(guò)程簡(jiǎn)述:??將class打包成dex?? 相關(guān)代碼:DexArchiveBuilderTransform.java

核心代碼解析:

定位到 ??transform()?? 方法,可以看到對(duì)class的處理分為了兩種,目錄下的 class和.jar里的class:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_33

跟下 ??processJarInput()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_34

繼續(xù)跟:??convertJarToDexArchive()??

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_35

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_36

對(duì)class兩種處理方式,最后都走到 ??convertToDexArchive()??,其中調(diào)用了 ??launchProcessing()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_jvm_37

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_38

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_39

這里的 ??dexArchiveBuilder.convert()?? 其實(shí)就是內(nèi)部調(diào)用dx或d8來(lái)打dex,跟下賦值處:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_android_40



22. transformDexArchiveWithExternalLibsDexMergerForDebug

過(guò)程簡(jiǎn)述:??打包第三方庫(kù)的dex?? 相關(guān)代碼:ExternalLibsMergerTransform.kt 核心代碼解析:

同樣跟 ??transform()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_41

創(chuàng)建了一個(gè) ??DexMergerTransformCallable?? 實(shí)例,然后調(diào) ??call()?? 方法:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_jvm_42

比較簡(jiǎn)單,就是調(diào)下dx或d8將上面生成的依賴(lài)庫(kù)的dex合并成一個(gè)dex。



23. transformDexArchiveWithDexMergerForDebug

過(guò)程簡(jiǎn)述:??打包最終的dex?? 相關(guān)代碼:DexMergerTransform.transform() → mergeDex() 核心代碼解析:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_43

跟下 ??submitForMerging()?? :

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_44

也是創(chuàng)建了一個(gè) ??DexMergerTransformCallable?? 實(shí)例,剩余邏輯同上~



24. mergeDebugJniLibFolders

過(guò)程簡(jiǎn)述:??合并jni lib文件?? 相關(guān)代碼:MergeSourceSetFolders.java



25. transformNativeLibsWithMergeJniLibsForDebug

過(guò)程簡(jiǎn)述:??合并jnilibs?? 相關(guān)代碼:MergeJavaResourcesTransform.java



26. transformNativeLibsWithStripDebugSymbolForDebug

過(guò)程簡(jiǎn)述:??去掉native lib里的debug符號(hào)?? 相關(guān)代碼:StripDebugSymbolTransform.java



27. processDebugJavaRes

過(guò)程簡(jiǎn)述:??處理java res?? 相關(guān)代碼:MergeJavaResourcesTransform.java



28. transformResourcesWithMergeJavaResForDebug

過(guò)程簡(jiǎn)述:??合并java res?? 相關(guān)代碼:MergeJavaResourcesTransform.java



29. packageDebug

過(guò)程簡(jiǎn)述:??打包APK?? 相關(guān)代碼:PackageApplication.java → PackageAndroidArtifact.doTask()

核心代碼如下:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_45

而上面的這些updateXxx()方法,調(diào)用的都是:??IncrementalPackager → updateFiles()??

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_46

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_gradle_47

最終調(diào)用mApkCreator.writeZip將上述內(nèi)容寫(xiě)入到APK中。



30. extractProguardFiles

過(guò)程簡(jiǎn)述:??生成混淆文件?? 相關(guān)代碼:ExtractProguardFiles.java



補(bǔ)充:錨點(diǎn)Task → 空Task

上面的Tasks過(guò)濾了錨點(diǎn)Task,啥事錨點(diǎn)Task?答:空Task,用來(lái)表明處于某種狀態(tài)。

以 ??preBuild?? 為例,全局搜它,定位到: ??TaskManager → MAIN_PREBUILD??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_移動(dòng)開(kāi)發(fā)_48

跟下引用處:??createTasksBeforeEvaluate()??:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_49

注冊(cè)了一個(gè)名為 **??MAIN_PREBUILD??**的Task,但沒(méi)有傳閉包(任務(wù)內(nèi)容),即空Task。



小結(jié)

以上就是本節(jié)的全部?jī)?nèi)容,看完好像懂了些什么,又說(shuō)不出來(lái)懂了什么,沒(méi)關(guān)系,畢竟有點(diǎn)偏理論,為后面Gradle的更深入學(xué)習(xí)及應(yīng)用做鋪墊而已,不急,有疑問(wèn)或文中有誤地方歡迎評(píng)論區(qū)指出,謝謝~

對(duì)了,喂,三點(diǎn)幾了:

補(bǔ)齊Android技能樹(shù)——從AGP構(gòu)建過(guò)程到APK打包過(guò)程_java_50

本文摘自 :https://blog.51cto.com/u

開(kāi)通會(huì)員,享受整站包年服務(wù)立即開(kāi)通 >