一篇文章带你了解Gradle插件的所有创建方式

Gradle中插件可以分为两类:脚本插件和对象插件。

脚本插件

脚本插件就是一个普通的gradle构建脚本,通过在一个foo.gradle脚本中定义一系列的task,另一个构建脚本bar.gradle通过apply from:'foo.gradle'即可引用这个脚本插件。

首先在项目根目录下新建一个config.gradle文件,在该文件中定义所需的task。

一篇文章带你了解Gradle插件的所有创建方式

 

//config.gradle
project.task("showConfig") {
     doLast {
        println("$project.name:showConfig")
    }
}

然后在需要引用的module的构建脚本中引用config.gradle,例如在app.gradle中,由于config.gradle建立在根目录下,与app这个模块平级,所以需要注意路径问题../config.gradle

//app.gradle
apply from: '../config.gradle'

就是这么简单,此时运行gradle构建即可执行showConfig这个task,

garretdeMacBook-Pro:CustomPlugin garretwei$ ./gradlew showConfig
> Task :app:showConfig
app:showConfig

对象插件

对象插件是指实现了org.gradle.api.Plugin接口的类。Plugin接口需要实现void apply(T target)这个方法。该方法中的泛型指的是此Plugin可以应用到的对象,而我们通常是将其应用到Project对象上。

编写对象插件主要有三种方式:

  1. 直接在gradle脚本文件中

  2. 在buildSrc目录下

  3. 在独立的项目下

在gradle脚本文件中

直接在gradle脚本中编写这个方式是最为简单的。打开app.gradle文件,在其中编写一个类实现Plugin接口。

//app.gradle
class CustomPluginInBuildGradle implements Plugin<Project> {
    @Override
    void apply(Project target) {
       target.task('showCustomPluginInBuildGradle'){
            doLast {
                println("task in CustomPluginInBuildGradle")
            }
        }
    }
}

然后通过插件类名引用它

//app.gradle
apply plugin: CustomPluginInBuildGradle

执行插件中定义的task

garretdeMacBook-Pro:CustomPlugin garretwei$ ./gradlew -q showCustomPluginInBuildGradle
task in CustomPluginInBuildGradle

在buildSrc目录下

除了直接写在某个模块的构建脚本中,我们还可以将插件写在工程根目录下的buildSrc目录下,这样可以在多个模块之间复用该插件。

虽然buildSrc是Gradle在项目中配置自定义插件的默认目录,但它并不是标准的Android工程目录,所以使用这种方式需要我们事先手动创建一个buildSrc目录。目录结构如下:

一篇文章带你了解Gradle插件的所有创建方式

buildSrc目录结构

 

在buildSrc/src/main/groovy目录下创建自定义plugin,并在build.gradle中引用groovy插件

//  buildSrc/build.gradle
apply plugin: 'groovy'
dependencies {
    compile gradleApi()
    compile localGroovy()
}

然后编写plugin代码

class CustomPluginInBuildSrc implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('showCustomPluginInBuildSrc') {
            doLast {
                println('task in CustomPluginInBuildSrc')
            }
        }
    }
}

由于buildSrc目录是gradle默认的目录之一,该目录下的代码会在构建是自动编译打包,并被添加到buildScript中的classpath下,所以不需要任何额外的配置,就可以直接被其他模块的构建脚本所引用。

注意这里引用的方式可以是通过类名引用,也可以通过给插件映射一个id,然后通过id引用。

通过类名引用插件的需要使用全限定名,也就是需要带上包名,或者可以先导入这个插件类,如下

apply plugin: com.gary.plugin.CustomPluginInBuildSrc

或者

import com.gary.plugin.CustomPluginInBuildSrc
apply plugin: CustomPluginInBuildSrc

通过简单的id的方式,我们可以隐藏类名等细节,使的引用更加容易。映射方式很简单,在buildSrc目录下创建resources/META-INF/gradle-plugins/xxx.properties,这里的xxx也就是所映射的id,这里我们假设取名myplugin。具体结构可参考上文buildSrc目录结构。

myplugin.properties文件中配置该id所对应的plugin实现类

implementation-class=com.gary.plugin.CustomPluginInBuildSrc

此时就可以通过id来引用对于的插件了

//app.gradle
apply plugin: 'myplugin'

在独立工程下

在buildSrc下创建的plugin只能在该工程下的多个模块之间复用代码。如果想要在多个项目之间复用这个插件,我们就需要在一个单独的工程中编写插件,将编译后的jar包上传maven仓库。

这里为了不增加复杂度,我们还是在该工程下创建一个standaloneplugin模块。只需要明白我们完全可以在一个独立的工程下来编写插件。

一篇文章带你了解Gradle插件的所有创建方式

standAlonePlugin目录结构

 

从目录结构来看,和buildSrc目录是一致的。区别在于buildSrc下的代码在构建时会自动编译并被引用。而我们在独立项目中编写的插件如果要能正确的被引用到,需要上传到maven仓库中,然后显式地在需要引用的项目中的buildSrcipt中添加对该构件的依赖。

插件代码

class StandAlonePlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('showStandAlonePlugin') {
            doLast {
                println('task in StandAlonePlugin')
            }
        }
    }
}

插件项目构建脚本

apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
    compile gradleApi()
    compile localGroovy()
}
group = 'com.gary.plugin'
version = '1.0.0'
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}

这里与buildSrc不同的是,我们引用了apply plugin 'maven',通过maven插件,我们可以轻松的配置group,version 以及 uploadArchives的相关属性,然后执行./gradlew uploadArchives这个任务,就可以将构件打包后上传到maven仓库了。同样为了示例简单,我们上传到一个本地仓库repository(url: uri('../repo'))中。

上传之后就可以在项目根目录下找到repo这个目录了。最后我们通过给根目录下的build.gradle配置buildScript的classpath,就可以引用这个插件了。注意,classpath的格式为group:artifact:version

buildscript {
    repositories {
        maven {
            url uri('repo')
        }
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.gary.plugin:standaloneplugin:1.0.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

引用插件

//app.gradle
apply plugin: 'standAlonePlugin'

执行StandAlonePlugin中定义的任务

./gradlew -q showStandAlonePlugin
task in StandAlonePlugin

总结

  • 插件分为脚本插件和对象插件。

  • 脚本插件通过apply from: 'foo.gradle'引用。

  • 对象插件可以在当前构建脚本下直接编写,也可以在buildSrc目录下编写,还可以在完全独立的项目中编写,通过插件类名或是id引用。apply plugin: ClassName或者apply plugin:'pluginid'

本文所编写的插件代码只是起到简单说明,主要介绍插件编写方式。实际插件编写过程中需要用到的Extension,以及Project和Gradle相关的生命周期方法等api并未涉及。相关知识点可以参考本系列文章中的【实战,从0到1完成一款Gradle插件】。

最后

更多Android进阶技术,面试资料系统整理分享,职业生涯规划,产品,思维,行业观察,谈天说地。可以加Android架构师群;701740775。

 

上一篇:centos/linux 安装node.js


下一篇:磁盘阵列介绍、进程的查看管理、日志文件的查看分析,systemctl的控制