打开:
指向:AppPlugin
类,跟下:
上节说过:插件类都继承于 Plugin
,入口函数 apply()
,但在这里没找到,跟下:AbstractAppPlugin
→ BasePlugin
。
① 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。
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()
方法:
作者2013年从java开发,转做Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。
参与过不少面试,也当面试官 面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!
我整理了一份阿里P7级别的最系统的Android开发主流技术,特别适合有3-5年以上经验的小伙伴深入学习提升。
主要包括阿里,以及字节跳动,腾讯,华为,小米,等一线互联网公司主流架构技术。如果你想深入系统学习Android开发,成为一名合格的高级工程师,可以收藏一下这些Android进阶技术选型
我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
Java语言与原理;
大厂,小厂。Android面试先看你熟不熟悉Java语言
高级UI与自定义view;
自定义view,Android开发的基本功。
性能调优;
数据结构算法,设计模式。都是这里面的关键基础和重点需要熟练的。
NDK开发;
未来的方向,高薪必会。
前沿技术;
组件化,热升级,热修复,框架设计
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多,GitHub可见;《Android架构视频+学习笔记》
当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。
不出半年,你就能看出变化!