前言

前面我们已经把gradle中groovy的一些语法,以及常用的project和task介绍了一遍,那么我们通过自己撸个插件。刚好把前面的内容巩固下。

插件的作用

首先我们需要了解下插件的作用,主要有如下几点:

  • 添加任务到项目中,可对项目进行测试、编译、打包;

  • 添加依赖到项目中,可用来配置项目构建过程中需要的依赖;

  • 可以向项目中现有的对象类型添加新的扩展属性、方法等,可方便项目的配置和构建优化,比如 Android 项目构建中的 android{} 就是AndroidGradle插件为Project 对象添加的一个扩展。

插件的分类

插件主要是分为两种:脚本式插件和二进制式插件。

脚本式插件

脚本式插件就类似于前面文章提到的,自己新建一个config.gradle,然后通过

1
apply from:"../config.gradle"

去引用config.gradle文件中的一些属性等,如可将某些工具性质的方法以及各个依赖使用的版本号分别定义到单个gradle文件中,方便统一调用和管理各个依赖的版本号等。

二进制式插件

二进制插件一般式之通过式Plugin接口,实现apply方法。该方法中的泛型指的是此Plugin可以应用到的对象,一般是将其应用到Project对象上。一般来说二进制插件分为三种方式:

  • Build script:直接在gradle脚本文件中实现plugin接口并应用,不适用于对外提供
  • buildSrc project: buildSrc是Gradle 在项目中配置自定义插件的默认目录。一般来说很少使用
  • Standalone project:独立的工程,编译后不仅可以对内也可以对外使用

前面两个应用场景很少,在这就不过多介绍了,想了解的可以自己百度一下~,我们着重介绍一下最后一个。

动手撸一个 Standalone project

既然是独立的工程,那么首先我们需要新建一个moudle。整个创建步骤如下:

  • 新建moudle,类型可以选择Android。然后把目录删干净,只留下build.gradle文件并把build.gradle内部清空。

  • 在moudle创建src/main/groovy目录,并新建其包名。同时在main目录下再新建resources/META-INF/gradle-plugins目录,在这个目录下编写一个和插件id名字相同的.properties文件,这样Gradle就可以找到插件实现了。

修改properties文件:

1
implementation-class=com.xxxx.plugin.MyGradlePlugin

修改build.gralde文件如下:

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
apply plugin: 'java-gradle-plugin'
apply plugin: 'kotlin'
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'maven-publish'

repositories {
mavenCentral()
}

group = '你的plugin包名'
version = '你的plugin版本号'

publishing {
repositories {
maven {
url = uri("$rootDir/repo")
}
}
publications {
maven(MavenPublication) {
from components.java
}
}
}

dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
//gradle sdk
implementation gradleApi()
//groovy sdk
implementation localGroovy()
}

依赖groovy相关插件是为了我们可以创建groovy文件。依赖maven是为了后续的本地上传以及调试。

现在我们先写一个简单的试试效果。在你的目录下新建一个plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

class MyGradlePlugin implements Plugin<Project> {

@Override
void apply(Project project) {
project.task('MyGradlePlugin') {
doLast {
println('task in MyGradlePlugin')
}
}

}
}

然后我们点击Gradle -> myGradlePlugin -> publishing -> publish。执行完成后,会在项目根目录下生成repo仓库。也就是之前在build.gradle中配置的url。

既然本地maven已经生成了,接下来就是我们的引用了。我们在根目录的build.gradle引用我们本地的maven。示例如下:

1
2
3
4
5
6
7
repositories {
google()
jcenter()
maven {
url = uri("$rootDir/repo")
}
}

本地maven依赖完成后,我们在根目录把自己引用的插件依赖下:

1
2
3
4
5
6
apply plugin: "myGradlePlugin"
dependencies {
...
classpath 'com.xxxx.plugin:myGradlePlugin:1.0.0'
...
}

然后我们sync一下。好了成功了。那我们如何验证我们自己写的plugin呢。我们在命令行输入:

1
./gradlew MyGradlePlugin

然后你会发现它输出了:

1
2
Task:MyGradlePlugin
task in MyGradlePlugin

卧槽,卧槽,成功了!!

我们加大点难度,我们需要在build.gradle动态一些属性,并且自己写的plugin可以读到这些动态配置的属性。既然需要动态配置属性,那我们先定义一下需要动态的属性,新建一个Extension。具体示例如下:

1
2
3
4
5
6
7
8
9
10
class MyGradlePluginExtension {
String versionName
String versionCode
String versionInfo

@Override
String toString() {
return "versionName = $versionName , versionCode = $versionCode , versionInfo = $versionInfo"
}
}

我们定义了版本的属性,比如版本号,版本名称,版本信息等等。既然定义了,那么我们怎么读取这些属性呢。修改我们的plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyGradlePlugin implements Plugin<Project> {

@Override
void apply(Project project) {
project.extensions.create("MyGradlePluginExtension", MyGradlePluginExtension.class)
project.task('MyGradlePluginExtension') {
doLast {
MyGradlePluginExtension releaseInfo = project.MyGradlePluginExtension
println releaseInfo
}
}

}
}

代码修改后,可以看到逻辑如下,创建一个MyGradlePluginExtension,然后定义一个task为MyGradlePluginExtension(我这边为了方便2个名称用的同一个,其实可以分开)。也就是说我们在执行MyGradlePluginExtension的Task时候,会读取project的MyGradlePluginExtension的属性,然后将其输出。

重新上传maven,这里就不多说了,前面有提到过,然后我们在根目录新增如下代码:

1
2
3
4
5
MyGradlePluginExtension {
versionName = 1.0
versionCode = 1.0
versionInfo = "测试第一版"
}

然后我们执行这个task,会看到面板输出如下:

1
2
Task :MyGradlePluginExtension
versionName = 1.0 , versionCode = 1.0 , versionInfo = 测试第一版

动态配置生效了~

总结

本节主要讲了Gradle插件的分类以及我们该如何去自己写一个插件并进行应用。更多自定义的操作可以查看官方文档:编写自定义插件