
使用Transform的常见场景有埋点统计、耗时监控、方法替换
通过上图以我们了解下transform的作用,transform在 class 到 dex 之间工作,处理包括 javac 编译后的字节码文件,每个 transform 都对应一个 Task,transform 的输入和输出对应 transform task 的输入输出。每个 transform task 的输出都分别存储在app\build\intermediates\transform\[Transform Name]\[Variant]下
Transfom 的几个核心API可以查看 buildSrc方式 - transform 下的介绍,这里我们着重挑 transform 方法做下介绍
@Override
void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
super.transform(transformInvocation)
println '转换开始........................'
def start = System.currentTimeMillis()
def inputs = transformInvocation.inputs
def outputProvider = transformInvocation.outputProvider
if (outputProvider != null)
outputProvider.deleteAll()
// transform 的 inputs 有两种类型:一种是目录,一种是jar包
inputs.each { input ->
// 本地 project 编译成的多个 class 文件存放的目录
input.directoryInputs.each { dir ->
handleDirectory(dir,outputProvider)
}
// 各依赖锁编译成的 jar 文件
input.jarInputs.each { jar ->
handleJar(jar, outputProvider)
}
}
def cost = (System.currentTimeMillis() - start) / 1000
println "转换结束............................:$cost"
}
jar和aar依赖方式参与构建的输入文件,包含本地依赖和远程依赖任何构建系统都会尽量避免重复执行相同工作,transform 也提供了这样的备选项
增量标记位
Task 增量模式与 Transform 增量模式区别
前者会跳过整个 Task 的动作列表,后者还是会依次执行 TransformTask,但输入内容胡增加变更内容信息
增量模式的输入
此模式下的输入都是带状态的,需要根据这些状态做不同处理,无需每次都执行所有流程;例如新增的输入需要处理,未修改的输入就无需处理,Transform 定义了4个输入文件状态
// com.android.build.api.transform\Status.java
@Deprecated
public enum Status {
// 未修改,无需处理,也无需复制操作
NOTCHANGED,
// 新增,正常处理并复制给下一个任务
ADDED,
// 已修改,正常处理并复制给下一个任务
CHANGED,
// 已删除,需同步移除 OutputProvider 指定的目标文件
REMOVED;
}
Gradle:com.android.tools.build:gradle-7.0.2.jar 下的 BaseExtension 中维护了 Transform 列表,自定义 Transform 需要注册才能生效,并且还支持设置 TransformTask 的依赖
// com.android.build.gradle\BaseExtension.kt
bstract class BaseExtension protected constructor(
protected val dslServices: DslServices,
protected val globalScope: GlobalScope,
...
):AndroidConfig, Lockable {
private val _transforms: MutableList<Transform> = mutableListOf()
/** Secondary dependencies for the custom transform. */
private val _transformDependencies: MutableList<List<Any>> = mutableListOf()
...
fun registerTransform(transform: Transform, vararg dependencies: Any) {
_transforms.add(transform)
_transformDependencies.add(listOf(dependencies))
}
}
注册 Transform:
// 获取 Android 扩展
val androidExt = project.extensions.getByType(BaseExtension::class.java)
// 注册 Transform,支持额外增加依赖
androidExt.registerTransform(MyTransform())