51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Gradle核心思想(六)自定义Gradle插件的三种方式

相关文章:

前言 {#前言}

在上一篇文章Gradle核心思想(五)通俗易懂的Gradle插件讲解中,我介绍了什么是Gradle插件、如何使用Gradle插件、Gradle插件的作用和好处,由于篇幅的原因,还有一个重要的知识点没有讲,那就是自定义Gradle插件(自定义Gradle对象插件)。自定义Gradle插件主要有三种方式,分别是build.gradle中编写、buildSrc工程项目中编写、独立项目中编写。建议阅读本文前,先阅读开头列出的本系列相关文章。

build.gradle {#build-gradle}

对象插件是实现了org.gradle.api.plugins接口的插件,这个接口中只定义个一个简单的apply方法,想要实现自定义插件就需要去实现org.gradle.api.plugins接口。
Groovy、Java、Kotlin都可以作为实现插件的语言,在本文的示例中,使用Groovy作为实现语言。
在实际工作中我们很少会在build.gradle中编写自定义插件,这里是为了带大家写个最简单的例子,可以最快最直接的了解什么是自定义插件。

简单的自定义插件 {#简单的自定义插件}

这里使用IntelliJ来编辑(AS也可以),首先新建一个Groovy工程:

定义项目的GroupId和ArtifactId:

build.gradle

|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 | apply plugin:CustomPlugin class CustomPlugin implements Plugin<Project> { @Override void apply(Project project) { project.task('CustomPluginTask') { doLast { println "自定义插件" } } } } |

在build.gradle中自定义了一个插件CustomPlugin,在apply方法中创建一个名称为CustomPluginTask的任务。在IntelliJ的Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务。

自定义插件扩展 {#自定义插件扩展}

再举一个简单的插件拓展例子,通过插件拓展来配置CustomPluginTask的输出字符串,如下所示。
build.gradle

|------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class CustomPluginPluginExtension { String message = 'from CustomPlugin' } class CustomPlugin implements Plugin<Project> { @Override void apply(Project project) { def extension = project.extensions.create('custom', CustomPluginPluginExtension)//1 project.task('CustomPluginTask') { doLast { println extension.message } } } } apply plugin: CustomPlugin custom.message = "自定义插件拓展"//2 |

CustomPluginPluginExtension类中定义了message变量,CustomPluginPluginExtension是一个Groovy Bean(类似于JavaBean)。注释1处用于添加拓展插件CustomPluginPluginExtension到插件列表中,名称为custom。注释2处设置CustomPluginPluginExtension的message值。
Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务。

buildSrc工程项目 {#buildSrc工程项目}

除了在build.gradle中编写的自定义插件,还可以将插件的源代码放在rootProjectDir/buildSrc/src/main/groovy目录中,Gradle会自动识别来完成编译和测试。
在第一节的工程根目录下建立/buildSrc/src/main/groovy目录,如下图所示。

在groovy目录中创建一个groovy文件,比如我的是CustomPlugin.groovy:
buildSrc/src/main/groovy/CustomPlugin.groovy

|------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 | import org.gradle.api.Plugin; import org.gradle.api.Project; class CustomPlugin implements Plugin<Project> { @Override void apply(Project project) { project.task('CustomPluginTask') { doLast { println "自定义插件" } } } } |

修改build.gradle为如下的内容:
build.gradle

|-----------|------------------------------------| | 1 | apply plugin: CustomPlugin |

Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务,会打印出我们想要的结果。

独立项目 {#独立项目}

无论是在build.gradle中编写自定义插件,还是buildSrc项目中编写自定义插件,都只能在自己的项目中进行使用。如果想要分享给其他人或者自己用,可以在一个独立的项目中编写插件,这个项目会生成一个包含插件类的JAR文件,有了JAR文件就很容易进行分享了。

自定义插件 {#自定义插件}

为了和前两种方式进行区分,用IntelliJ新建一个Groovy工程,我的工程名为CustomPluginShare,后面会用到。
配置build.gradle

|---------------------|-------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 | apply plugin: 'groovy' dependencies { compile gradleApi() compile localGroovy() } |

应用Groovy插件,并将Gradle API添加为编译时依赖项,build工程,会在External Libraries中生成三个jar文件:

这样我们可以在非buildSrc工程项目中使用groovy语法和Gradle的api了。
创建自定义插件
在src/main/groovy/ 目录中创建一个包,我的是com.example.plugins,在com.example.plugins创建一个groovy文件:
src/main/groovy/com/example/plugins/CustomPlugin.groovy

|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.example.plugins import org.gradle.api.Plugin import org.gradle.api.Project class CustomPlugin implements Plugin<Project> { @Override void apply(Project project) { project.task('CustomPluginTask') { doLast { println "自定义插件" } } } } |

配置properties文件
在buildSrc工程项目中,Gradle可以自动的去识别插件,独立项目中的插件是如何被Gradle识别的呢?答案是需要在生成的JAR文件中提供一个属性文件,这个属性文件名要与插件id相匹配。在resources中创建src/main/resources/META-INF/gradle-plugins/com.example.plugins.customplugin.properties,这个属性文件的名称实际就是插件的id。将properties文件的内容改为:

src/main/resources/META-INF/gradle-plugins/com.example.plugins.properties

|-----------|---------------------------------------------------------------| | 1 | implementation-class=com.example.plugins.CustomPlugin |

implementation-class属性为自定义插件的名称。

上传插件
这里为了方便举例直接将插件上传到本地,如果想要发布到Maven、ivy等仓库,见下面的文档:
https://docs.gradle.org/4.4/userguide/publishing_ivy.html
https://docs.gradle.org/4.4/userguide/publishing_maven.html
想要发布到Gradle插件门户上,见下面的文档:
https://docs.gradle.org/4.4/userguide/plugins.html#sec:plugins_block
在build.gradle文件中添加如下内容:

|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 | apply plugin: 'maven' group = 'com.example.plugins' version = '1.0.0' uploadArchives { repositories { mavenDeployer { repository(url: uri('../repo')) } } } |

这段代码会将生成的插件上传到项目的平级目录repo下。定义了group和version的名称,这些值会在其他项目依赖该插件时用到。我们Build后会在Gradle窗口中看到uploadArchives,如下图所示。

点击uploadArchives会在本地生成插件相关的文件,比如我的目录和文件如下图所示。

图中的CustomPluginShare-1.0.0.rar就是我们需要的插件jar包。

在另一个项目中使用插件 {#在另一个项目中使用插件}

新建一个Groovy项目,我取名为Projet,build.gradle的代码如下:

|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 | apply plugin: 'com.example.plugins.customplugin' buildscript { repositories { maven { url uri('../repo') } } dependencies { classpath 'com.example.plugins:CustomPluginShare:1.0.0' } } |

其中com.example.plugins是group,CustomPluginShare是自定义插件的名称,1.0.0是版本号,也可以这么写:

|-----------------|--------------------------------------------------------------------------------------------------------------| | 1 2 3 4 | dependencies { classpath group: 'com.example.plugins', name: 'CustomPluginShare', version: '1.0.0' } |

Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务,大功告成。
如果我们将自定义插件发布到Gradle插件门户上,就可以使用插件DSL了:
build.gradle

|---------------|---------------------------------------------------------------------------| | 1 2 3 | plugins { id 'com.example.plugins.customplugin' version '1.0.0' } |

虽然讲解独立项目的例子超级简单,但我还是将代码上传到GitHub上了,也许会有同学用的上:
https://github.com/henrymorgen/CustomPlugin

总结 {#总结}

本篇文章介绍了自定义Gradle插件的3种方式,旨在以最简单的例子来让大家快速掌握,如果还想了解复杂的自定义插件可以去查看一些开源的Gradle插件,或者在工作中去实践。本篇文章也为学习Android Gradle插件打下了伏笔。

参考链接:http://liuwangshu.cn/application/gradle/6-custonplugin.html


赞(3)
未经允许不得转载:工具盒子 » Gradle核心思想(六)自定义Gradle插件的三种方式