结合booster wiki以及官方博客学习booster的代码。
booster主要分为两个部分,一个是基于其task spi的自定义task,一个是基于transformer api 自定义 transformer,我的理解,其中所说的spi类似api一样的存在.
SPI全称Service Provider Interface,在Java中还是一个比较重要的概念,是Java提供的一套用来被第三方实现或者扩展的API,或者换句话说,SPI是一种服务发现机制。(摘之仓颉博客)
task spi
task的api仅仅是对gradle原生的BaseVariant 进行了一个简单的包装使用
interface VariantProcessor {
fun process(variant: BaseVariant)// 变量为原生gradle类
}
transform spi
transformer稍微复杂些,首先在booster-transform-spi中定义了一系列interface,其中TransformListener 是对其自身 transform生命周期的监听,TransformContext是transform的上下文环境,其中主要包含一系列变量,例如transform name, project dir, build dir, temp dir . eg, 另外还有Transformer 为正主,Klass 特殊定义class,ArtifactManager artifacts常量的管理,KlassPool 根据name获取对应的Klass
这些都是其自己为了transform自定义的一些api,具体地和正宗的transform对接是在 booster-gradle-plugin 模块中,这里的booster transform继承了gradle的transform中,然后在 BoosterTransformInvocation 完成自定义transform spi和gradle transform的语义转换和对接
final override fun transform(invocation: TransformInvocation?) {
invocation?.let {
BoosterTransformInvocation(it).apply {
dumpInputs(this)
if (isIncremental) {
onPreTransform(this)
doIncrementalTransform()
}
// 很多代码
}
}
Build参数解析
buildsrc里面负责各个plugin的参数解析,主要工作是由BuildPropsPlugin以及BuildPropsGenerator完成,而BuildPropsPlugin由booster.gradle apply导入,主要是该Plugin在apply里面做了很多解析和生成工作,而每一个plugin均有apply booster.gradle
package com.didiglobal.booster.transform.thread;
// 生成文件举例
public interface Build {
String GROUP = "com.didiglobal.booster"; // 组信息
String ARTIFACT = "booster-transform-thread"; // 名称
String VERSION = "0.22.0"; // version
String REVISION = "3da1b919b1df72891993a98ac0fb80bffd4b3e8c";
}
一个典型transform gradle
apply from: '../gradle/booster.gradle' // 解析build参数,例如目标路径保存形式等等
dependencies {
// AutoService : A configuration/metadata generator for java.util.ServiceLoader-style service providers
kapt "com.google.auto.service:auto-service:1.0-rc4" // auto注解解析
// 提供通用util功能,提供booster对于gradle的部分包装使用
implementation project(':booster-android-gradle-api')
implementation project(':booster-task-spi') // task spi
implementation project(':booster-transform-asm')
// transform spi 具体实现(asm实现)
compileOnly 'com.android.tools.build:gradle:3.0.0'
testCompileOnly 'com.android.tools.build:gradle:3.0.0'
}
在具体项目中包含对应的基本元素就可以开发出一个针对性的优化项检测或者插入字节码实现具体功能,这些模块最终根据产生的build文件打包成aar形式,使用的时候通过
classpath "com.didiglobal.booster:booster-gradle-plugin:$booster_version" // 引入需要集成的模块,还有对相应仓库的引入
知识点:
Gradle是一个编译框架类似ant / maven, 主要由两部分组成分别是task和transform,前者接触最多,例如 gradle clean,这个就是一个clean task, transform主要是在编译过程中实现各种转换的功能,例如现在的使用asm插入字节码,就是使用transform达到目的
DSL 是 Domain Specific Language 的缩写,既领域专用语言;
kapt 是Kotlin 的注解解析声明方式,类似annotationProcessor;
Gradle 5.0版本之前DSL语言仅仅为groovy,5.0之后增加kotlin作为DSL,所以再看xx.gradle文件时里面虽然是groovy的写法,但是可能包含kotlin语法。