Gradle基本使用(2):基本概念与Task

时间:2023-01-17 11:42:53

Gradle 基本使用

Project 和 Task

Project 和 Task 是 Gradle 中的2个重要概念,类似于 Ant 中的 target 和 task 的关系,Project为一个待编译的gradle,一个 project 中可以包含一个或多个 task,每一个 task 用于标记一个构建任务;
一个基本的 build.gradle 构建脚本如下:
123 命令行定位到该 build.gradle 所在目录,执行 "gradle -q hello" 即可执行脚本;
gradle 构建脚本文件以“.gradle”为尾缀,通过命令行启动的脚本的方式见下; gradle 脚本使用 groovy 编写,所以在 gradle 脚本任意位置可以使用 groovy 代码;


Task 的定义和使用

1)定义 task 

每一个 task 含有2个基本的属性,doFirst ,doLast,在常用有以下 2 种定义方式: build.gradle 1
//方法1:直接定义
2
task hello {
3
    doFirst{
4
        println 'task begin';
5
    }
6
    doLast{
7
        println 'hello world!';
8
    }
9
}
10
11
//方法2:通过属性调用
12
task hello
13
hello.doFirst{
14
    println 'task begin';
15
}
16
hello.doLast{
17
    println 'hello world!';
18
}
19
//doLast 可以使用 << 符号标记(短标记法)
20
task hello 
21
hello.doFirst{
22
    println 'task begin';
23
}
24
hello << {
25
    println 'hello world!'
26
}
27
//甚至简写为以下:
28
task hello <<{
29
    println 'hello world!'
30
}
31
hello.doFirst{
32
    println 'task begin';
33
}

执行以上 task ,在命令行中定位到该 build.gradle 文件所在目录,“gradle -q hello”即可执行任务 hello,关于 gradle 命令行的详细使用见下面;
设置默认 task 对于一个构建文件中的多个 task,可以设置默认的 task,当执行“gradle -q ”指令不声明调用某个具体的task时,会调用该task: 123 设置 task 描述 可以对一个task设置一个描述,用于说明该 task 的作用,当执行gradle tasks" 时候会显示这些信息 1
task hello <<{
2
    description 'This is test task'
3
    println 'hello world!'
4
}
设置 task 额外属性 task 除了doFirst,doLast 属性之外,可支持自定义属性,声明方式在task内部代码区,使用“ext.属性名”即可声明该 task 的一个额外属性,如下示例: 123456 启用/禁用 task 可以在 build.gradle 中手动启用或禁用 task,默认下 task 是开启状态; 1
task myTask << {
2
    ......
3
}
4
5
myTask.enabled = false;  //禁用myTask
6
myTask.enabled = true;   //启用myTask

2)使用 groovy 代码

在 gradle 任意位置可以使用 groovy 代码,包括 task 内部,task外部,这实际上使得 gradle 脚本的编写十分灵活和强大(groovy可以调用Java类库),如下: 123456789101112131415161718192021222324252627282930313233

3)task 执行顺序

一个task中可以有多个 doFirst 和 doLast 属性,当调用一个 task 时,这些代码的执行顺序如下:
  • 先顺序执行所有 task 的 doFrist,doLast 属性之外的代码;
  • 再执行 doFirst 属性,多个 doFirst 存在时,先执行代码中最后加入的 doFirst;
  • 再执行 doLast 属性,多个 doLast 存在时,先执行代码中最先加入的 doLast;
如下示例: 1
println 'pre-1'
2
    
3
task testTask {
4
    println 'pre-2'
5
}
6
testTask.doFirst{
7
    println 'doFirst-1'
8
}
9
testTask.doFirst{
10
    println 'doFirst-2'
11
}
12
testTask << {
13
    println 'doLast-1'
14
}
15
testTask << {
16
    println 'doLast-2'
17
}
18
19
20
task otherTask {
21
    println 'pre-3'
22
}
执行"gardle -q testTask "后输出如下:
pre-1 pre-2 pre-3 doFirst-2 doFirst-1 doLast-1 doLast-2
这里要注意的是,所有task 的 doFirst,doLast 属性之外的代码的影响都是本脚本全局的,所以在这些公共全局区域编写代码时要特别谨慎,尽量将代码编写到 doFirst,doLast,以保持每一个 Task 的独立性;

4)task 依赖

类似于 Ant 中 task 的依赖,可以对 gradle 的 task 设置依赖,当一个 task 执行时,会先执行该 task 所依赖的 task,由此形成灵活的多条任务调用链; gradle 中声明一个 task 的依赖有2种方式: ① 直接声明 123456789101112 执行 “gradle -q myTask4 ”输出:
This is preTask1 This is preTask2 This is myTask3 This is myTask4
② 延迟声明 1
task preTask1 << {
2
    println "This is ${preTask1.name}"
3
}
4
task preTask2 << {
5
    println "This is ${preTask2.name}"
6
}
7
task myTask1 << {
8
    println "This is ${myTask1.name}"
9
}
10
task myTask2 << {
11
    println "This is ${myTask2.name}"
12
}
13
myTask1.dependsOn preTask1,preTask2
14
myTask2.dependsOn myTask2
使用延迟声明可以在 dependsOn 方法使用一个闭包作为参数,如下: 123

5)跳过 task

在执行task链时,有时会根据实际的情况而跳过某些task,gradle提供了多种方法来实现这一过程,这里介绍使用断言的方法: 以下示例: 1
def flag = false;   //某个判断条件变量
2
 
3
task myTask1 << {
4
    println "This is ${myTask1.name}"
5
}
6
task myTask2 (dependsOn : myTask1)<< {
7
    println "This is ${myTask2.name}"
8
}
9
myTask2.onlyIf{ flag == true }    //当 flag == false 跳过 myTask2
10
11
task myTask3 (dependsOn : myTask2 )<< {
12
    println "This is ${myTask3.name}"
13
}
执行"gradle -q myTask3 ",输出如下: 
This is myTask1 This is myTask3

也可以通过以下方式,实现在命令行指令控制task是否跳过: 1234567891011 执行"gradle -q myTask3 -P skipMyTask2",(其中 -P 参数是为 project 增加属性)输出如下: 
This is myTask1 This is myTask3

6)在 task 中执行其他 task

可以在代码任意地方通过调用 taskName.execute() 的方法来显示执行该task; 在某个task中调用某个task,示例如下: 1
task myTask1 << {
2
    println "Hello world"
3
}
4
task myTask2 (dependsOn : myTask1)<< {
5
    println "This is ${myTask2.name}"
6
    myTask1.execute()      //调用myTask1
7
}
通过这种方法,可以很方便的将多个单元task耦合到一个task逻辑中,其中比实用的例子是在一个task中调用多个gradle api task(比如 gradle自带的文件处理api task,详见:05. Gradle 文件操作


Gradle 基本命令行

1)执行 task

比如执行当前目录下的 build.gradle 中的 task hello ; 1 以上命令中 -q 参数为控制台显示日志的级别:
  • -q 为显示quiet及更高级别;
  • -i 为显示info及更高级别;
  • -d 为显示debug及更高级别;

以上命令中省略了 build.gradle 的文件路径参数,在默认下为找到的第一个 gradle 构建脚本,如果当前目录存在多个构建文件,可以显示指定调用的构建脚本,使用 -b 指定路径参数,如下调用当前目录下的 "build2.gradle"中的 task "hello": 1
gradle -q -b build2.gradle hello

2)排除 task

可以使用 -x 参数来排除某些任务,一但某个任务被排除,那么该任务依赖的其他任务链不会执行; 如 build.gradle 存在任务依赖链 task1 -> task2 -> task3 -> task4 ; 正常调用 task4 ,执行顺序为 task1,task2,task3,task4,如果如下面调用 task4时排除 task3 ,那么只会执行 task4,task3之前的依赖关系任务都不会执行: 1
3)简化调用 task 名 gradle 命令行支持 task名称的简化调用和驼峰简化调用,如下指令是相同的: 1
gradle -q helloWorld
2
gradle -q he      //简化task名
3
gradle -q hW      //驼峰式简化task名

4)显示脚本信息

12
以上是一些常用的Gradle命令行指令,更多指令参见官方文档:https://docs.gradle.org/4.2/userguide/tutorial_gradle_command_line.html


Gradle 插件体系


Gradle 对于各种常见的工程构建,比如 Java 工程构建,Groovy 工程构建等,是以插件的形式来提供支持,当构建脚本中需要某一个插件时,加载该插件即可,Gradle 本身包含一个标准插件库,同时也支持第三方的插件,可自己实现插件并使用到构建脚本中;
把插件应用到项目中可以让插件来扩展 project 的功能:
  • 将任务添加到项目 (如编译、 测试)
  • 使用有用的默认设置对已添加的任务进行预配置。
  • 向项目中添加依赖配置 。
  • 通过扩展对现有类型添加新的属性和方法。

比如应用标准插件库中的 Java 插件: 1
apply plugin: 'java'  
关于 Java 项目构建,参见:http://blog.csdn.net/al_assad/article/details/78074183 关于依赖配置,参见:http://blog.csdn.net/al_assad/article/details/78074155 关于 Gardle 完整的插件库信息,参见:https://docs.gradle.org/4.2/userguide/plugins.html