实例讲解Gradle的生命周期与核心概念
Gradle是一个自动化的构建工具。要掌握好gradle的用法,我们需要先对它的生命周期和核心概念有所了解。
Gradle的核心概念有project和task。Gradle的生命周期包括初始化、配置、执行。
下面我们从一个实例来讲解,在其生命周期的三个阶段,针对project和task,都分别做了什么。
1. 工程目录结构
工程目录结构2. 执行命令
在命令行中执行如下命令
$ gradle :projectA:childA1:world
:projectA:childA1:world标识了一个task的路径。其中:projectA:childA1为project的路径,world为该project中的一个task。
Gradle是如何找到对应的project和task的呢?又是在什么时候执行的task呢?
3. Gradle的生命周期
(1)Initialization-初始化阶段
这个阶段会执行settings.gradle文件,创建project树。
settings.gradle内容如下:
//settings.gradle
println("initialization from settings")
include ":projectA:childA1"
include ":projectA:childA2"
include ":projectB"
:projectA:childA1表示childA1是projectA的子project,根目录对应的是rootProject。根据settings文件,最后创建的project树如下:
project树状结构需要注意的是,project的树状关系一般是和目录结构保持一致的,也可以不一致。比如我们可以在settings中写
include “:projectA:projectB"
这样的话,projectB的父project就变成了projectA。如果这样写的话,会报错说找不到projectB,因为默认情况下Gradle会在projectA目录下面找。我们可以用下面这句话改变project的路径:
project(":projectA:projectB").projectDir = new File("projectB")
(2)Configuration-配置阶段
初始化阶段创建完了project,然后便会按照广度优先的顺序,针对每个project对象,执行其中的build.gradle脚本。
我们的例子中build.gradle的内容都一样,如下所示:
// build.gradle
println "configuration ${project.path}”
task("hello").doLast{
println("hello from ${project.path}")
}
task("world").doLast {
println("world from ${project.path}")
}
tasks.getByName("world").dependsOn("hello")
task(“hello")其实就是在调用:projectA:childA1这个project对象的task方法,这个project对象就是在前面的初始化阶段创建的。task方法的作用是用来在project中创建一个task,task的名字为hello。
这个脚本中一共创建了两个task,分别为hello和world。tasks是project中的一个字段,类型为TaskContainer。一个project 的所有task都会保存在这个TaskContainer中。接下来通过task的dependsOn方法,在hello和world之间创建了依赖关系。
所有的task会形成一个有向无环图。
println "configuration ${project.path}”, 这一句在该阶段就会执行,输出一条日志。
doLast是task的一个回调方法,该回调会在下面的执行阶段执行。
(3)Excution-执行阶段
配置完了就到了执行阶段,我们要执行的是projectA:childA1下的world task。gradle会根据task的依赖关系图,从前往后执行。本例中的world task依赖于hello task,而hello不依赖与任何的task,所以先执行hello,然后再执行world。这两个task都属于同一个project,我们也可以在不同project的task之间建立依赖关系。比如:
tasks.getByName("world").dependsOn(“:projectB:hello")
task有doFirst和doLast两个关键方法,它们可以在task执行前后追加命令,构成了两个链表。比如:
tasks.getByName("world").doFirst {
println "first 1"
}
tasks.getByName("world").doFirst {
println "first 2"
}
tasks.getByName("world").doLast {
println "last 1"
}
tasks.getByName("world").doLast {
println "last 2"
}
最后的输出是
first2
first1
last1
last2
注意是first2在first1之前执行
- 输出结果
我们最初的例子的输出结果如下
输出结果从输出的结果里面可以验证Gradle生命周期的三个阶段。
参考资料:
Gradle的官网是最好的资料,建议有英文阅读能力的直接看官网
Gradle用户手册:https://docs.gradle.org/current/userguide/userguide.html
Gradle Build Lifecycle: https://docs.gradle.org/current/userguide/build_lifecycle.html#build_lifecycle_events