Gradle Plugin

Gradle Plugin

能够允许我们在编译出的 jar 或 class 文件之后打包成 apk 之前修改文件

插件可以拿 java 、kotlin 或 groovy语言编写

自定义插件、扩展和配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 实现Plugin接口
class BenBenPlugin implements Plugin<Project> {
@Override
void apply(Project target) {
def extension = target.extensions.create("benben", BenBenExtension) // 引入扩展并重命名
println "1: ${extension.name}" // 会在 apply 后调用,输出:1: benben extension
target.afterEvaluate {
println "2: ${extension.name}" // 会在配置完扩展后调用,输出:2: benben config
}
}
}
// 自定义扩展
class BenBenExtension {
def name = "benben extension"
}
apply plugin: BenBenPlugin // 引入插件
benben {
name "benben config" // 配置扩展
}
构建Gradle Plugin库
  1. 在项目新建 buildSrc/src/main/groovy/<包名>/<插件文件>.groovy 文件
  2. 在 main 目录内添加插件声明 resources/META-INF/gradle-plugins/<插件声明>.properties
  3. 在需要使用插件的库中引用:apply plugin: ‘<插件声明>’,参考原生插件

注意:

如果在实现Plugin时没有对应的包,则需要参考上图 build.gradle 配置 gradle 依赖

不要在settings.gradle中声明 buildSrc 库,该库为默认引用

Transform
  1. 声明 Transform

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    package com.benben.plugin

    import com.android.build.api.transform.Format
    import com.android.build.api.transform.QualifiedContent
    import com.android.build.api.transform.Transform
    import com.android.build.api.transform.TransformException
    import com.android.build.api.transform.TransformInvocation
    import com.android.build.gradle.internal.pipeline.TransformManager
    import com.android.utils.FileUtils

    class BenBenTransform extends Transform {

    @Override
    String getName() {
    return 'benben' // 任务名称:可以在gradle的 app/Tasks/other 中找到 transformClassesWith<任务名>For<构建类型>
    }

    @Override
    Set<QualifiedContent.ContentType> getInputTypes() {
    return TransformManager.CONTENT_CLASS // 要处理的输入类型
    }

    @Override
    Set<? super QualifiedContent.Scope> getScopes() {
    return TransformManager.SCOPE_FULL_PROJECT // 要处理的项目范围
    }

    @Override
    boolean isIncremental() {
    return false
    }

    /**
    * 这里只是简单的进行中转,并没有对文件做任何操作
    */
    @Override
    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
    def inputs = transformInvocation.inputs // 输入文件
    def outputProvider = transformInvocation.outputProvider // 输出目的地
    inputs.each {
    it.jarInputs.each {
    File dest = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.JAR)// 获取jar文件目标地址
    println "Jar:${it.file},Dest:${dest}"
    FileUtils.copyFile(it.file, dest) // 将输入的文件拷贝到目标目录
    }
    it.directoryInputs.each {
    File dest = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.DIRECTORY)// 获取目录目标地址
    println "Dir:${it.file},Dest:${dest}"
    FileUtils.copyDirectory(it.file, dest) // 将输入的目录拷贝到目标目录
    }
    }
    }
    }
  2. 注册

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class BenBenPlugin implements Plugin<Project> {

    @Override
    void apply(Project target) {
    def transfrom = new BenBenTransform()
    def baseExtension = target.extensions.getByType(BaseExtension)
    baseExtension.registerTransform(transfrom)
    }
    }

注意:

如果已经注册了Transfrom,就必须实现transform方法来实现文件输出

正常情况下会通过 javassistASM等字节码处理库对中间文件进行修改