Android Gradle Transform使用
一.概述
gradle用于构建项目,其plugin插件用于完成一特定功能,而有些时候我们希望在插件中完成对项目内容的一些更改,这就需要我们在gradle构建过程中,获取到源文件才能进行,所幸的是,gradle plugin从1.5.0版本开始,为我们提供了Transform功能,它可以以输入输出流的链式方式,供我们对源文件进行处理
自gradle plugin3.0开始,对于引入gradle plugin有一些问题,需要进行兼容,下面会有说到
二.使用
(一)引入
一般我们在根项目中的build.gradle中的buildscript中引入gradle plugin脚本,而要引入Transform功能,需要在任意module的build.gradle中的dependencies引入
compile "com.android.tools.build:gradle:2.3.3"
这里需要注意的是,在3.0后,对于gradle plugin的仓库位置发生变化,需要在buildscript和module中的repositories中使用google()仓库:
repositories {
google()
...
}
引入后我们就可以看到Transform等类了
(二)API
然后我们先来看看Transform功能的结构
1.QualifiedContent
该接口定义了一个输入内容的基本实现,有name和file,此file可能有两种形式,文件夹和jar包,于是对应的分为两个实现类,DirectoryInput和JarInput
2.TransformInput
对于每一个输入流来说,内容既可能有一组文件夹,也可能有一组jar包,TransformInput类为一个输出流的标准实现
3.TransformOutputProvider
既然有了input,对应的就要有output,output的位置不能由我们私自决定,需要通过TransformOutputProvider的getContentLocation()获取
4.TransformInvocation
将以上输入输出流信息包装为TransformInvocation对象,这也是3.0之后的一个改变,之前只是将各个参数直接传递给Transform
5.ContentType
对于输出内容,我们可以指定想要获取的输入内,ContentType中设定了几种类型:
-
CLASSES:字节码文件
-
RESOURCES:资源文件
6.SCOPE
除了ContentType,还可以指定整个Transform的作用域,SCOPE中设定了几种类型:
-
PROJECT:主项目
-
SUB_PROJECT:子项目
-
PROJECT_LOCAL_DEPS:主项目的本地依赖
-
SUB_PROJECT_LOCAL_DEPS:子项目的本地依赖
-
EXTERNAL_LIBRARIES:依赖库
在3.0后,两个LOCAL_DEPS已经废弃了,都归为EXTERNAL_LIBRARIES
7.TransformManager
3.0开始,gradle为我们提供了TransformManager类,里面的一些常量帮我们指定了一些常用的ContentType和Scope,比如:
-
SCOPE_FULL_PROJECT:包括了PROJECT、SUB_PROJECT、EXTERNAL_LIBRARIES,也是最常用的一个
-
CONTENT_CLASS:包括了CLASSES,也是最常用的一个
8.Transform
最后我们来说Transform,其需要重写的几个方法:
-
getName():为Transform定义一个名字,不过该名字最后生成的文件名,也是拼接上了flavor、buildType等等
-
getInputTypes():该方法返回的就是一组ContentType,用于限定接受的输入内容类型
-
getScopes():该方法返回的就是一组Scope,用于限定transform的作用域
-
isIncremental():该方法是指定该Transform是否使用增量构建模式
-
transform():该方法就是实际转换时候调用的方法,3.0之前将input、outputProvider等传入,3.0开始直接将一个TransformInvocation对象传入
(三)使用流程
1.添加至构建
有了Transform,需要把它加入到构建中:
project.extensions.getByType(AppExtension).registerTransform(new MyLogTransform())
AppExtension就是我们android的gradle plugin的Extension对象,即我们在build.gradle中的android{}配置模块,其中的registerTransform方法添加一个Transform对象
2.构建流程
-
项目中可以加入多个Transform,比如已经有ProGuardTransform、DexTransform等
-
每个Transform的输出作为下一个Transform的输入,前一个Transform的output,会根据下一个Transform的contentTypes和scopes,将相应的内容传入到下一个Transform的inputs中
-
Transform在添加时,会将其包装为一个Task
public <T extends Transform> Optional<AndroidTask<TransformTask>> addT