Transform介绍(1)

img

使用Transform的常见场景有埋点统计、耗时监控、方法替换

通过上图以我们了解下transform的作用,transform在 class 到 dex 之间工作,处理包括 javac 编译后的字节码文件,每个 transform 都对应一个 Task,transform 的输入和输出对应 transform task 的输入输出。每个 transform task 的输出都分别存储在app\build\intermediates\transform\[Transform Name]\[Variant]

1. transform 方法

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"
    }
  • getInputs:获取 TransformInput 对象,它是消费型输入内容,对应 getScopes() 定义的范围,transformInput 由两部分组成
    • DirectoryInput 集合:以源码方式参与构建的输入文件,包括完整的源码目录结构及其中的源码文件
    • JarInput集合:以jaraar依赖方式参与构建的输入文件,包含本地依赖和远程依赖
  • getOutPutProvider:获取 TransformOutputProvider 对象,它是对输出文件的描述,它有两个功能
    • deleteAll:当 transform 以非增量构建模式时,需要删除上一次构建产生的所有中间文件,可以使用该方法
    • getContentLocation:获得指定范围+类型的输出目标路径

2. transform 增量模式

任何构建系统都会尽量避免重复执行相同工作,transform 也提供了这样的备选项

  1. 增量标记位

    • Transform#isIncremental():返回 true 才会触发增量模式
    • TransformInvocation#isIncremental():表示 TransformTask 是否增量执行
  2. Task 增量模式与 Transform 增量模式区别

    前者会跳过整个 Task 的动作列表,后者还是会依次执行 TransformTask,但输入内容胡增加变更内容信息

  3. 增量模式的输入

    此模式下的输入都是带状态的,需要根据这些状态做不同处理,无需每次都执行所有流程;例如新增的输入需要处理,未修改的输入就无需处理,Transform 定义了4个输入文件状态

    // com.android.build.api.transform\Status.java
    @Deprecated
    public enum Status {
        // 未修改,无需处理,也无需复制操作
        NOTCHANGED,
        // 新增,正常处理并复制给下一个任务
        ADDED,
        // 已修改,正常处理并复制给下一个任务
        CHANGED,
        // 已删除,需同步移除 OutputProvider 指定的目标文件
        REMOVED;
    }
    

3. 注册 Transform

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())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值