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

阅读 230
收藏 16
2018-05-29
原文链接:mp.weixin.qq.com

本文由玉刚说写作平台提供写作赞助

赞助金额:300元 原作者:竹千代 版权声明:未经本公众号许可,不得转载

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

脚本插件

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

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

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

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

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

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

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

对象插件

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

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

  1. 直接在gradle脚本文件中

  2. 在buildSrc目录下

  3. 在独立的项目下

在gradle脚本文件中

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

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

然后通过插件类名引用它

//app.gradleapply plugin: CustomPluginInBuildGradle

执行插件中定义的task

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

在buildSrc目录下

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

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

buildSrc目录结构

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

//  buildSrc/build.gradleapply 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.CustomPluginInBuildSrcapply 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.gradleapply plugin: 'myplugin'

在独立工程下

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

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

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.gradleapply plugin: 'standAlonePlugin'

执行StandAlonePlugin中定义的任务

./gradlew -q showStandAlonePlugintask in StandAlonePlugin

总结

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

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

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

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

欢迎长按下图 -> 识别图中二维码或者 扫一扫 关注我的公众号

也想获得写作赞助?点击下面的 阅读原文  来加入玉刚说写作平台 吧!

评论