文章目录
Gradle构建过程
根据在上图中所示,Gradle的生命周期可以分为三大步:
- Initialization 初始化阶段
- Configuration 配置阶段
- Execution 执行阶段
1. Initialization 初始化阶段
在Gradle项目中,支持构建单个或者多个子工程,在初始化阶段,就是解析settings.gradle,根据在执行的项目,gradle找出哪些项目依赖需要参与到构建中,为每个module创建对应的 project实例。
Project实例是什么?为什么在项目中没有见过呢?其实你见过了,就是项目里的build.gradle。build.gradle文件就是Gradle中的一个Project对象实例。那么Gradle是怎么确定哪些工程需要参与编译的呢?根据Settings类。根据Settings类?这个好像见过,对,就是项目中的settings.gradle。
setting.gradle
...
// 通过include函数,将moudule的名字(文件夹名包含进来)
include ':app'
include ':aap'
include ':module1'
现在知道settings.gradle中的include ':app’是怎么肥事了吧。
当前项目的根目录,也就是settings.gradle所在的目录会默认生成一个Project对象。
gradle的主要对象
Gradle基于Groovy,Groovy又基于Java。所以,Gradle执行的时候和Groovy一样,会把脚本转换成Java对象。Gradle主要有三种对象,这三种对象和三种不同的脚本文件对应,在gradle执行的时候,会将脚本转换成对应的对象。
-
Settings对象:每个settings.gradle会转换成一个Settings对象。
-
Project对象:每个build.gradle会转换成一个Project对象。
-
Gradle对象:构建初始化时创建,整个构建执行过程中只有这么一个对象,一般很少去修改这个默认配置脚本。当我们执行gradle xxx或者什么的时候,gradle会从默认的配置脚本中构造出一个Gradle对象。
监听初始化阶段代码:
setting.gradle
...
//1.setting.gradle 执行结束的监听
gradle.settingsEvaluated {
println "settings.gradle 初始化执行结束"
}
//2.参与构建的Project对象创建完毕的监听
gradle.projectsLoaded {
Gradle gradle ->
println "settings.gradle 所有在 settings 中 include 的 Project 都创建完成了"
}
2. Configuration 配置阶段
配置阶段就是执行各个子工程下的build.gradle脚本完成Project对象的配置,一个Project包含很多Task,每个Task之间有依赖关系。会建立一个有向图来描述Task之间的依赖关系图,以便在执行阶段执行。
监听配置阶段代码
roomProject build.gradle
...
// 对每一个 project 在执行配置代码之前都会回调这个方法
// 模块的配置顺序是根据应用名字按字典顺序进行配置的。gradle.beforeProject 自己不执行,自己后面的要配置的模块都会执行一次
gradle.beforeProject {
Project project ->
println ">>>>>>>>gradle beforeProject " + project.name + " 配置开始前回调 "
}
// 没有执行
project.beforeEvaluate {
Project project ->
println ">>>>>>>>project.beforeEvaluate " + project.name + " 配置开始前回调 "
}
// project在执行配置代码之前的回调 只有自己的模块会执行
project.afterEvaluate {
Project project ->
println "----------project.afterEvaluate " + project.name + " 配置结束监听 "
}
// project在执行配置代码之前的回调 当前模块和之后的模块都会执行
gradle.afterProject {
Project project ->
println "----------gradle.afterProject " + project.name + " 配置结束监听 "
}
// 所有的 project 都执行完对应的 build.gradle 的配置代码,准备要去生成对应的 Task 依赖图
// 放在哪个模块的build.gradle执行效果都是一样的。
gradle.projectsEvaluated {
gradle ->
println "所有的project都配置完毕了,准备生成Task依赖关系"
}
// 表示 "task 依赖关系已经生成"
// 放在哪个模块的build.gradle执行效果都是一样的。
gradle.taskGraph.whenReady {
TaskExecutionGraph graph ->
println "task 依赖关系已经生成"
}
注意:
-
模块的配置顺序是根据应用名字按字典顺序进行配置的。
举例:本工程共有三个子工程,分别是aap、aap、module1。这三个模块在配置阶段按照字典顺序进行执行,即aap->app->module1。最开始配置的是rootProject 的build.gradle。所以配置阶段顺序就是 rootProject->aap->app->module1。
-
gradle.beforeProject 在本模块不会执行,后面的要配置的模块都会执行一次
举例:我在aap 模块 build.gradle中 编写gradle.beforeProject,在配置阶段aap模块中并不会执行,后面,aap和module1模块都会执行一次。同理:如果aap模块定义gradle.beforeProject,只有module1模块配置阶段汇之行】
-
gradle.afterProject 当前模块和之后的模块都会执行
-
project 是build.gradle实例,在build.gradle使用project ,project相当于this,模块中使用Project的方法只会在当前模块执行。
-
project.beforeEvaluate 这个方法不会执行,project.afterEvaluate在当前模块配置阶段执行。
3.Execution 执行阶段
执行阶段就是把根据配置阶段生成的任务依赖关系图挨个顺序执行任务。
这一步是根据传入的参数执行task的。比如 assembleDebug这样的。
task是Gradle中执行的最小单元
监听执行阶段代码
// 每一个 Task 任务执行之前回调
gradle.taskGraph.beforeTask {
Task task ->
println "Project[${task.project.name}]--->Task[${task.name}] 在执行之前被回调"
}
// 每一个 task 执行之后被回调
gradle.taskGraph.afterTask {
task, TaskState taskState ->
//第二个参数表示 task 的状态,是可选的参数
println "Project[${task.project.name}]--->Task[${task.name}] 在执行完毕,taskState[upToDate:${taskState.upToDate},skipped:${taskState.skipped},executed:${taskState.executed},didWork:${taskState.didWork}]"
}
构建结束之后的回调
// 当所有的任务执行完毕的回调
gradle.buildFinished {
BuildResult buildResult ->
println "构建完毕"
}
执行clean任务 输出结果
代码地址:gradle生命周期