Gradle自定义Plugin的三种方式

410 阅读4分钟

Gradle自定义Plugin的三种方式

gradle是Android中管理与发布project的工具,利用gralde我们可以在编译以及发布阶段做很多自定义操作,例如修改报名,多渠道发布,分渠道打包,字节码修改等等。这些功能的实现都涉及到了gradle中的project、task以及gradle执行生命周期等的概念,自定义plugin与transform都是建立在这些概念之上的。在这篇文章中,首先来了解一下如何自定义Plugin

如何创建自定义plugin

方式一:

可以直接在项目的build.gradle中定义插件,然后直接使用就可以了例如在app的build.gradle中定义如下插件:

class CustomTestPlugin implements Plugin<Project> {

    @Override
    void apply(Project target) {
        target.task('CustomTestPlugin', group: 'util') {
            doLast {
                println 'Its my custom plugin'
            }
        }
    }
}

然后直接apply使用即可:

apply plugin: CustomTestPlugin  // 注意不要带单引号

在Sync 后,点开右侧边栏的 “Gradle” 菜单,就可以看到自定义的插件了:

image-20200927173442457

我们可以在底部选择Terminal window,执行 ./gradlew CustomTestPlugin ,就可以看到插件的输出了,这里我们是添加到了生命周期 doLast 执行的时候。

image-20200927173602885

方法一在日常工作中用的并不多, 因为我们可能需要定义很多插件,如果每个插件都写在build.gradle里面,耦合度太高,因此还有第二种方法:

方法二:

在同一个项目内,创建一个新的buildSrc文件夹,如下目录结构:

image-20200927173851129

在创建了buildSrc之后,可以点:File -> Sync Project with Gradle Files 选项,这时IDE会自定识别buildSrc目录,生成.gradlebuild , 然后创建 src -> main -> groovy。之后可以根据自己的需要创建包名,最后创建一个自定义插件类:CustomPlugin.groovy, 该类写法与方法一一样:

import org.gradle.api.Plugin
import org.gradle.api.Project

class CustomPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('CustomPluginTask') {
            println '自定义插件'
        }
    }

}

运行方法与方法一一样,./gradlew CustomPluginTask 就可以看到输出了。

方法三:

可以像打包一个aar的方式一样,将插件发布出去,这也是用的比较多的方式:

首先可以新建一个module,module的目录结构和方法二中的buildSrc目录结构一样。只是将buildSrc换成是module的名字,然后将module中除了src之外的多余文件都删除,和上面的buildSrc目录结构一致即可:

image-20200927201117793

其中CustomMavenTestPlugin与前面的自定义插件内容一样,只是名字与输出不一样,就不贴出来了。然后需要将这个module publish到本地/远程仓库,需要定义build.gradle如下:

apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'java'

dependencies{
    implementation gradleApi()
    implementation localGroovy()
}

group = 'com.example.maven.plugin'
version="1.0"

uploadArchives{
    repositories {
        flatDir {
            dirs '../repo/'
        }
    }
}
  1. 如上图,其中'maven-publish' 是为了publish 这个maven仓库引入的插件,可以看到文件中还有 group与version的定义,group就是要输出的maven仓库的group_id,输出的maven仓库的artifact_id就是这个module的名字,再加上version就是maven仓库的路径:'com.example.maven.plugin:plugin-lib:1.0'。 可以看到,后面还定义了一个task,uploadArchives,主要是为了将aar打包并输出到上一级的repo目录。

  2. 在src目录下,新建一个与groovy同级的目录resources,然后新建子文件夹 META-INF/gradle.plugins,创建文件custom-maven-plugin.properties:

    implementation-class = com.example.plugin.CustomMavenTestPlugin
    

    注意这里的文件custom-maven-plugin 就是导出后的gradle plugin的id,而implementation-class 是为了声明对应着哪个plugin。

  3. 完成后,直接运行 ./gradlew :plugin-lib:uploadArchives , 就可以在项目的根目录/repo下生成了jar包。

  4. 在项目的build.gradle下添加该repo的路径,为了能找到对应的jar包:

    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    
    buildscript {
        ext.kotlin_version = '1.3.41'
        repositories {
            google()
            jcenter()
            flatDir {
                dirs './repo/'
            }
    
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.3.2'
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
            classpath 'com.example.maven.plugin:plugin-lib:1.2'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
            flatDir {
                dirs './repo/'
            }
    
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
    

    如上所示,添加了 ./repo/ 路径仓库后,添加 classpath 'com.example.maven.plugin:plugin-lib:1.2'依赖,就可以在app的build.gradle中使用自定义的插件了:

    apply plugin: 'custom-maven-plugin'
    

    如果将上述推送到本地的操作,发布到远程,就可以不用依赖本地仓库也可以使用gradle 插件了。