补齐Android技能树——从AGP构建过程到APK打包过程

:app:assembleDebug → 空task,锚点

:app:extractProguardFiles → 生成混淆文件

还会打一个release包,task和上述基本一致,此处省略~

当然,也可以直接在 Build 窗口直接查看,双击右侧Gradle窗口中assemble的Task,然后观察此窗口:

啧啧,还可以看到每个Task的执行时间,不错,但先不跟每个Task具体内容,而是跟下AGP的构建过程~

0x5、AGP的构建过程


上一节将Gradle插件时说过,每个插件都会配置一个 id名字.properties 的文件,在此写上插件的实现类,全局搜定位到下述文件:

打开:

指向:AppPlugin 类,跟下:

上节说过:插件类都继承于 Plugin,入口函数 apply(),但在这里没找到,跟下:AbstractAppPluginBasePlugin

① BasePlugin

行吧,在BasePlugin中重写了 apply() 方法,里面调用了两个函数,先跟下:basePluginApply()

执行一些检查操作,接着是 插件的初始化及配置,而另一个函数:pluginSpecificApply() 则是空实现,接着跟下:配置项目、配置扩展及创建Tasks的过程。

② configureProject() → 配置项目

创建DataBindingBuilder实例,强制使用不低于当前所支持的最小插件版本,应用Java插件,如果启用了构建缓存选项,创建buildCache实例,添加了一个回调:所有project执行完后执行资源回收相关操作。

③ configureExtension() → 配置DSL扩展

完成下述几项工作:

  • ① 创建build.gradle中的Android DSL;

  • ② 创建VariantFactory、TaskManager、VariantManager实例;

  • ③ 注册新增/移除配置的回调,包括:signingConfig,buildType,productFlavor;

  • ④ 创建默认的debug签名、debug和release两种buildType;

④ createTasks() → 创建Tasks

跟下 createAndroidTask()

跟下 createAndroidTasks()

注意下:这里遍历了所有的variantScope,然后调用 createTasksForVariantData() 创建变体数据对应的Tasks:

跟下:createTasksForVariantScope()

抽象方法,看下哪里实现了这个方法,搜下:extends TaskManager

最终定位到了:ApplicationTaskManager

噢吼,就是在这里完成APK打包过程的Tasks,可以简单跟跟验证下:createAnchorTasks(),创建锚点Tasks:

跟下:createVariantPreBuildTask()

2333,跟上面的APK打包Task链的相呼应,AGP插件的构建过程就跟到这里,接着了解下APK打包的Task。

0x6、Apk的打包过程


Tips:分享下搜索Task的实现类的技巧 → 全局搜 “xxx”, “yyy” 即可快速定位对应Task类,如 “compile”, “Aidl”,或者搜索整个Task,然后删删删匹配。

1. compileDebugAidl

过程简述:将.aidl文件通过aidl工具转换成编译器能够处理的Java接口文件 相关代码:AidlCompile.java → AidlProcessor.java → call()


2. checkDebugManifest

过程简述:检查AndroidManifest.xml文件是否存在 相关代码:CheckManifest.java


3. compileDebugRenderscript

过程简述:处理Renderscript文件(.rs) 相关代码:RenderscriptCompile.java


4. generateDebugBuildConfig

过程简述:生成 BuildConfig.java 文件 相关代码:GenerateBuildConfig.java


5. mainApkListPersistenceDebug

过程简述:持久化APK数据到apk-list.gson中 相关代码:MainApkListPersistence.kt


6. generateDebugResValues

过程简述:遍历res下的values目录下xml文件,生成resValues文件generated.xml 相关代码:GenerateResValues.java → generate() → ResValueGenerator.java


7. mergeDebugResources

过程简述:使用AAPT2合并资源文件 相关代码:MergeResources.doFullTaskAction() → ResourceMerger.mergeData() → MergedResourceWriter.end() → mResourceCompiler.submitCompile() → AaptV2CommandBuilder.makeCompileCommand()

核心源码解析:

实现了isIncremental()方法,返回true,说明支持增量编译,跟下全量编译方法 doFullTaskAction()

ResourcePreprocessor preprocessor = getPreprocessor();

List resourceSets = getConfiguredResourceSets(preprocessor)

接着往下走:

继续:

点进merger.mergeData() → ResourceMerger.mergeData() → DataMerger.mergeData()

呕吼,实际上调用的还是 MergedResourceWriter 类里的方法,跟下addItem():

不同文件会创建对应的 CompileResourceRequest 实例,并添加到 mCompileResourceRequests 中,后者是一个ConcurrentLinkedQueue队列,资源最后会在end()方法处处理:

最终调用 AaptV2CommandBuilder.makeCompileCommand() 方法生成aapt2命令去处理资源。

Tips:将图片转为webp格式的插件一般在此Task前处理~


8. createDebugCompatibleScreenManifests

过程简述:manifest文件中生成compatible-screens,用于屏幕适配 相关代码:CompatibleScreensManifest.kt


9. processDebugManifest

过程简述:合并AndroidManifest.xml文件 相关代码:ProcessApplicationManifest.java、ProcessLibraryManifest.java


10. processDebugResources

过程简述:调用aapt2 link 打包资源并生成R.java文件 相关代码:TaskManager.java → createProcessResTask()


11. compileDebugKotlin

过程简述:编译Kotlin文件为字节码 相关代码:没找到…可能在kotlin插件源码里


12. prepareLintJar

过程简述:拷贝lint jar包到指定位置 相关代码:PrepareLintJar.java


13. avaPreCompileDebug

过程简述:生成annotationProcessors.json文件 相关代码:JavaPreCompileTask.java


14. ompileDebugJavaWithJavac

过程简述:编译java文件 相关代码:AndroidJavaCompile.java


15. compileDebugNdk

过程简述:编译NDK 相关代码:NdkCompile.java


15. mergeDebugShaders

过程简述:合并Renderscript文件(.rs) 相关代码:MergeSourceSetFolders.java


16. compileDebugShaders

过程简述:编译Renderscript文件(.rs) 相关代码:ShaderCompile.java


17. mergeDebugAssets

过程简述:合并assets文件 相关代码:MergeSourceSetFolders.java


18. validateSigningDebug

过程简述:验证签名 相关代码:ValidateSigningTask.kt 附加信息:检查当前Variant的签名配置中是否存在密钥库文件,如果当前密钥库默认为debug keystore,那密钥库不存在也会进行相应的创建。


19. signingConfigWriterDebug

过程简述:编写SigningConfig信息 相关代码:SigningConfigWriterTask.kt


20. checkDebugDuplicateClasses

过程简述:检查重复class 相关代码:CheckDuplicateClassesTask.kt 附加信息:检查项目外部依赖是否不包含重复类,打包成dex的时候再检测报错不怎么友好,所以引入了这个Task用于快速失败。


21. transformClassesWithDexBuilderForDebug

过程简述:将class打包成dex 相关代码:DexArchiveBuilderTransform.java

核心代码解析:

定位到 transform() 方法,可以看到对class的处理分为了两种,目录下的 class和.jar里的class:

跟下 processJarInput()

继续跟:convertJarToDexArchive()

对class两种处理方式,最后都走到 convertToDexArchive(),其中调用了 launchProcessing()

这里的 dexArchiveBuilder.convert() 其实就是内部调用dx或d8来打dex,跟下赋值处:


22. transformDexArchiveWithExternalLibsDexMergerForDebug

过程简述:打包第三方库的dex 相关代码:ExternalLibsMergerTransform.kt 核心代码解析:

同样跟 transform()

创建了一个 DexMergerTransformCallable 实例,然后调 call() 方法:

比较简单,就是调下dx或d8将上面生成的依赖库的dex合并成一个dex。


23. transformDexArchiveWithDexMergerForDebug

过程简述:打包最终的dex 相关代码:DexMergerTransform.transform() → mergeDex() 核心代码解析:

跟下 submitForMerging()

也是创建了一个 DexMergerTransformCallable 实例,剩余逻辑同上~


24. mergeDebugJniLibFolders

过程简述:合并jni lib文件 相关代码:MergeSourceSetFolders.java


25. transformNativeLibsWithMergeJniLibsForDebug

过程简述:合并jnilibs 相关代码:MergeJavaResourcesTransform.java


26. transformNativeLibsWithStripDebugSymbolForDebug

过程简述:去掉native lib里的debug符号 相关代码:StripDebugSymbolTransform.java


27. processDebugJavaRes

过程简述:处理java res 相关代码:MergeJavaResourcesTransform.java


28. transformResourcesWithMergeJavaResForDebug

过程简述:合并java res 相关代码:MergeJavaResourcesTransform.java


29. packageDebug

过程简述:打包APK 相关代码:PackageApplication.java → PackageAndroidArtifact.doTask()

核心代码如下:

而上面的这些updateXxx()方法,调用的都是:IncrementalPackager → updateFiles()

最终调用mApkCreator.writeZip将上述内容写入到APK中。


30. extractProguardFiles

过程简述:生成混淆文件 相关代码:ExtractProguardFiles.java


补充:锚点Task → 空Task

上面的Tasks过滤了锚点Task,啥事锚点Task?答:空Task,用来表明处于某种状态

preBuild 为例,全局搜它,定位到: TaskManager → MAIN_PREBUILD

跟下引用处:createTasksBeforeEvaluate()

注册了一个名为 **MAIN_PREBUILD**的Task,但没有传闭包(任务内容),即空Task。


总结:

各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,



    《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
    表明处于某种状态**。

preBuild 为例,全局搜它,定位到: TaskManager → MAIN_PREBUILD

跟下引用处:createTasksBeforeEvaluate()

注册了一个名为 **MAIN_PREBUILD**的Task,但没有传闭包(任务内容),即空Task。


总结:

各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,

    [外链图片转存中…(img-E0NLcWPm-1715366128574)]
    [外链图片转存中…(img-ZvID2ZUy-1715366128575)]
    《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值