深入理解Booster(三)-理解task以及build 产物的关系

659 阅读4分钟

一次编译到底要经过哪些task?

很多人可能很疑惑,一次android的编译过程到底要经过哪些task,谁先谁后? 不同的agp版本 这些task 又有什么异同?理解这个概念很关键,因为当你想对编译过程做一些 干预或者修改的时候 你必须十分清楚这个过程,否则 根本无从下手

收看下这个命令:

/gradlew :app:assembleDebug --dry-run

注意我这个agp版本是3.3

image.png

大家可以看下在agp3.3 下 ,一次编译要经过哪些task

红色箭头其实就是表示 我自定义了一个task 将这个task 设置在了 transformNativeLibsWithMergeJniLibsForDebug 与 processDebugJavaRes 之间

再看看 在agp 7.x 下 一次编译要经过哪些task?

image.png

大家可以仔细比较一下 2个版本之间的差异

task的输入输出 来猜测 task的作用

其实agp的编译说来也并不复杂,这些task其实就是头尾相接的链表而已,后一个task有时候会读取前一个task的产物,从而将编译进行下去

举个例子:

比如说agp 7.x 我们都知道andorid编译的过程会将所有的aar 中的so 最终都放到一个libs下面对吧 既然有这个任务 我们其实就可以在编译的过程中 获取到每个so的源文件了

可以看下 下面这张截图:

image.png

你看在7.x版本中 我们就可以在路径 app/build/intermediates/merged_native_libs 看到这些so了, 注意文件夹的名字 merged_native_libs

是不是一眼就能猜到这个 文件夹是哪个task 任务生成的?

同样的我们还可以看下 agp 3.3 版本看看这个版本是如何做到的?

image.png

是不是有很大的不同? 同样的 我们根据这个路径 再通过之前的dry run 命令 是不是也可以猜测到 在agp3.3中 这个 task是哪个?

很容易就猜到 是 :app:transformNativeLibsWithMergeJniLibsForDebug 这个task吧

理解Booster中重要的 task 路径以及 task

有了前面的基础 我们就不难理解 Booster中 对task以及对应产物的 重要抽象了

比方说 在深入理解Booster 二中 我们 初步了解了cwebp压缩的逻辑

大家应该对这2个扩展函数/属性 有印象

image.png

首先看这个

variant.mergedRes

他其实就是对下图的文件夹下的所有文件做了一个collection 从而方便开发者 去直接获取文件

image.png

他的架构实现做的其实也很简单 稍微跟一跟代码:

image.png

image.png

重要的就是在这里了 image.png

我们看下7.0的吧

其实到这里就是在用agp本身的函数了 image.png

Booster好用的地方就在于 插件开发者只要关注这个就可以扩展属性或者扩展函数就可以了,其内部的实现都帮你做好了,比如不同版本的文件夹路径 真的都一样吗? 其实也未必,大家有兴趣可以自行探索下 其他扩展函数

同样的我们再看看这个

variant.mergeResourcesTaskProvider

他的作用就是方便你直接取 mergeRes 这个task,这样你可以方便的将任务插在 这个task之后或者之前

从而不用关心不同的agp版本 mergeRes的取得方式

可以稍微看下源码:

image.png

image.png

image.png

注意看下这个task name 他其实也是agp本身的函数了 image.png

一般而言 一个重要的build路径 总是要伴随着对应的task的。

了解上面booster 对task的 扩展 会对你对booster的掌握很有帮助

如何调试booster源码

之前有人问到 自己如何调试booster源吗呢, 这里介绍个简单的方式

首先 改下版本号

image.png

然后把根目录下面的build文件 做一下修改 注释掉部分语句

image.png

然后就就可以publishToMavenLocal啦

直接执行这个任务即可 image.png

最后就是你自己的demo 宿主工程中 引入你这个版本号的booster即可

image.png

注意有的task 不会带到 agp编译的过程中,需要你手动去触发他

./gradlew tasks --all

可以通过上面这个命令来获取全部的task