Gradle Transform 详解

我们先来看下Android应用程序打包流程:

通过上图可知,我们只要在图中红色箭头处拦截(生成class文件之后,dex文件之前),就可以拿到当前应用程序中所有的.class文件,再去借助ASM之类的库,就可以遍历这些.class文件中所有方法,再根据一定的条件找到需要的目标方法,最后进行修改并保存,就可以插入我们的埋点代码。

Google从 Android Gradle 1.5.0 开始,提供了Transform API。通过Transform API,允许第三方以插件的形式,在Android应用程序打包成dex文件之前的编译过程中操作.class文件。我们只要实现一套Transform,去遍历所有.class文件的所有方法,然后进行修改(在特定的listener回调中插入埋点代码),再对源文件进行替换,即可以达到插入代码的目的。

Gradle Transform概述

Gradle Transform是Android官方提供给开发者在项目构建阶段(.class -> .dex转换期间)用来修改.class文件的一套标准API,即把输入的.class文件转变成目标字节码文件。目前比较经典的应用是字节码插桩、代码注入等。

我们build一个项目,会打印出如下日志,红框框住的部分就是一个Transform的名称

通过上张图可以看到原生就带了一系列Transform供使用,那么这些Transform是怎么组织在一起的呢,我们用一张图表示:

每个Transform其实都是一个gradle task,Android编译器中的TaskManager将每个Transform串连起来,第一个Transform接收来自javac编译的结果,以及已经拉取到在本地的第三方依赖(jar、aar),还有resource资源,注意,这里的resource并非android项目中的res资源,而是asset目录下的资源。 这些编译的中间产物,在Transform组成的链条上流动,每个Transform节点可以对class进行处理再传递给下一个Transform。我们常见的混淆,Desugar等逻辑,它们的实现如今都是封装在一个个Transform中,而我们自定义的Transform,会插入到这个Transform链条的最前面。

但其实,上面这幅图,只是展示Transform的其中一种情况。而Transform其实可以有两种输入,一种是消费型的,当前Transform需要将消费型型输出给下一个Transform,另一种是引用型的,当前Transform可以读取这些输入,而不需要输出给下一个Transform,比如Instant Run就是通过这种方式,检查两次编译之间的diff的。

最终,我们定义的Transform会被转化成一个个TransformTask,在Gradle编译时调用。

Transform两个基础概念

  • TransformInput
  • TransformOutputProvider

TransformInput

TransformInput是指输入文件的一个抽象,包括:

  • DitectoryInput集合
    是指以源码的方式参与项目编译的所有目录结构及其目录下的源码文件

  • JarInput集合
    是指以jar包方式参与项目编译的所有本地jar包和远程jar包(此处的jar包包括aar)

TransformOutputProvider

之Transform的输出,通过它可以获取到输出路径等信息

Transform.java

先来了解下Transform类,定义如下

public abstract class Transform {
    public Transform() {
    }

    // Transform名称
    public abstract String getName();

    public abstract Set<ContentType> getInputTypes();

    public Set<Conten
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值