extensions

Gradle是支持配置,外部的配置文件来设置插件的一些输入条件,在插件中是通过extensions实现的。

配置

如我们在项目的build.gradle下配置如下:

1
2
3
4
5

cyMessage {
message = 'hello '
greeter = 'cyning'
}

这代表一条这条消息,message代表消息内容,greeter代表消息源。

那么插件如何获取这条消息呢?
我们需要在Plugin来注册一个实体类来获取。

1
2
3
void apply(Project project) {
def extension = project.extensions.create("cyMessage", Message)
}

实体

其中Message是个实体类:


代码片段 1
1
2
3
4
public class Message {
String message = "empty"
String greeter = "none"
}

使用

我们可以自己写一个task(下一节就是会介绍task)来验证extensions获取是否成功。

代码片段 2
1
2
3
4
5
6
7
8
9
def extension = project.extensions.create("cyMessage", Message)

project.task('sendMessage') {
doLast {
println "${extension.message} from ${extension.greeter}"
println project.cyMessage.message + "from ${extension.greeter}"

}
}

可以注意到

1.extensions.create("cyMessage", Message)返回的是Message的实例

2.通过extensions.createproject注册了一个cyMessage`的属性。

所以获取代码片段中的message也有两种方式”
${extension.message}project.cyMessage.message

Task

Task是我们插件的任务单位,也就是说插件实际上就是一个个task,还记得我们常用的clean命令,实际上clean也是task,在android项目中,我们可以用gradlew tasks来查看这个项目中的task。

每个task实际上是可以分组的,如上图的Android tasks Build tasks,每个任务后面的小字实际上是task的描述,

task的创建

task目前可以有多种方法创建和操作。

gradle脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

task hello1 << {
println 'hello1'
}

task hello2 {
doLast {
println 'hello2'}
}

task hello3 {
println "task ----"
}

// 类似于<< 不过新版本已经弃用
hello3.leftShift {
print("hello world 3")
}
  1. doLast相当于是在任务执行Task结束前要执行的,是这个Task的最后一个步骤。
  2. <<leftShift是同一个意思也表示在相当于是在任务执行Task结束前要执行的,

groovy脚本创建

gradle脚本能容易写出脚本,但是对于一些复杂的Task还是需要我们用groovy来实现,可以控制控制他的灵活度。
我们可以来写我们的第一个Task.

1
2
3
4
5
6
7
8
9
10
11
public class FirstTask extends DefaultTask {

String message = 'This is default message'

// @TaskAction 表示该Task要执行的动作,即在调用该Task时,hello()方法将被执行
@TaskAction
def hello(){
println "Hello world. $message"
}

}

@TaskAction有注释,我就不再重复了,$message是我们内部定义的一个变量,默认是message

我们用这个task时只需要,写入我们的type为FirstTask.

1
2
3
4
5
6
7
// hello使用了默认的message值
task task1(type:FirstTask)

// 重新设置了message的值
task task2(type:FirstTask){
message ="I am an android developer"
}

task 属性

dependsOn可以关联依赖关系, group更像是我们的java代码的报名,是task的一种表示,多个task可以熟悉同一个group, description是我们在编写task的介绍,你可以认为是task的一种注释.

1
2
3
4
5
6
7
// 定义一个名字为rygTask的task,属于renyugang分组,并且依赖myTask1和myTask2两个task。
project.task('hello', group: "cc.cyning", description: "我自己的Task", dependsOn: ["task1", "task2"] ) </br>
.doLast {
println "execute rygTask"
}

`

这样helloTask就在task1task2执行完后,继续执行。

使用

可以直接在终端下输入

1
./gradlew :app:task2

app就是引入我们的task的项目,当然你可以可以用android studio的GUI界面.

taskextensions自定义插件

使用extensions传参,使用 task来实现功能,我们可以来尝试下,写自己的插件了,有了taskextensions这个两个概念以及自己的学习能力,写个简单的插件应该问题不大吧。

我也改造了Gradle插件开发(1) - Hello world的插件,下载地址:ownwell/Gradle-plugin

1
git clone -b v1.0 https://github.com/ownwell/Gradle-plugin.git

参考

  1. 创建Task的多种方法

  2. Writing Custom Plugins