Android Transform API

作者: changer0 | 来源:发表于2020-07-26 21:49 被阅读0次

    上一章知道如何自定义 Gradle插件后,我们到底可以用来做什么呢?难道只是用来定义一些简单的 Task?本章给你答案!

    什么是 Transform API

    Android Gradle 工具从 1.5.0-beta1 版本开始,包含了 Transform API,它允许第三方插件在将编译后的类文件转换为 dex 文件之前对 .class 文件进行操作。

    Transform 的工作原理

    接下来看下它的工作原理:

    Transform 工作原理
    • 很明显它是一个链式结构,每个 Transform 都是一个 Gradle 的 Task,Android 编译器通过 TaskManager 将每个 Transform 串联起来。
    • 第一个 Transform 接收 javac 编译的结果,以及 jar 包依赖和 resource 资源,这些编译的中间产物在 Transform 链上流动。其中,我们自定义的 Transform 会插入到最前面

    Transform API 的使用

    Transform API 其实就是继承自 Transform 写一个实现类,我们看下 Transform 需要实现的方法:

    Transform 需要实现的方法

    简单介绍下这几个方法:

    getName():用于指定 Transform 的名字,对应了该 Transform 所代表的 Task 的名称,例如:

    image

    isIncremental():方法指明是否支持增量编译。

    getInputTypes():用于指定 Transform 的输入类型,可以作为输入过滤的一种手段。在 TransformManager 中定义了很多类型:

    • CONTENT_CLASS // 代表 javac 编译成的 class 文件(一般用它)
    • CONTENT_JARS
    • CONTENT_RESOURCES // 这里的 resources 单指 java 的资源
    • CONTENT_NATIVE_LIBS
    • CONTENT_DEX
    • CONTENT_DEX_WITH_RESOURCES
    • DATA_BINDING_BASE_CLASS_LOG_ARTIFACT

    getScopes():用于指定 Transform 的作用域。同样在 TransformManager 中定义了很多类型,常用的是 SCOPE_FULL_PROJECT,即代表所有 Project。

    确定了 ContentType 和 Scope 后就确定了该自定义 Transform 需要处理的资源流。
    例如,上面提到的常用输入类型(CONTENT_CLASS)和常用作用域(SCOPE_FULL_PROJECT)表示的就是 所有项目中 java 编译成的 class 组成的资源流

    接下来我们来看需要复写的核心方法:

    image

    TransformInvocation 接口定义如下:

    image

    看下 TransformInput 的接口定义:

    所谓 Transform 就是对输入的 class 文件转变成目标字节码文件,TransformInput 就是这些输入文件的抽象。目前它包括两部分:DirectoryInput 集合与 JarInput 集合。

    image

    TransformOutputProvider 通过调用 getContentLocation 来获取输出目录:

    image

    复写完 Transform 的核心方法之后,我们需要通过插件注册它才可使用:

    image

    整体看下 CustomTransform 类:

    image

    接下来看下读取 class 文件的流程:

    image

    Demo 工程

    Android 工程:https://github.com/changer0/ASMInjectDemo

    以上就是本节内容,欢迎大家关注👇👇👇

    长按关注

    相关文章

      网友评论

        本文标题:Android Transform API

        本文链接:https://www.haomeiwen.com/subject/ymgglktx.html