有道无术,术尚可求,有术无道,止于术。
Gradle 的核心是一种基于依赖的编程语言。在Gradle 术语中,这意味着您可以定义任务和任务之间的依赖关系。Gradle 保证这些任务按照它们的依赖顺序执行,并且每个任务只执行一次。
这些任务形成了一个有向无环图。有一些构建工具可以在执行任务时构建这样的依赖关系图。Gradle 在执行任何任务之前构建完整的依赖关系图。这是 Gradle 的核心,它使许多原本不可能的事情成为可能。
Gradle 构建具有三个不同的阶段。
初始化:Gradle 支持单项目和多项目构建。在初始化阶段,Gradle 确定哪些项目将参与构建,并为每个项目创建一个Project实例。
配置:解析所有project中的build.gradle文件获取所有的task,形成有向无环图后执行依赖关系。并且所有project中的build script部分和task的配置段会在这一阶段调用(注意并不是执行具体的task代码)。
执行任务:Gradle 确定在配置阶段创建和配置的要执行的任务子集。该子集由传递给gradle命令和当前目录的任务名称参数确定。Gradle 然后执行每个选定的任务。
除了构建脚本文件,Gradle 还定义了一个settings 文件,该文件由 Gradle 通过命名约定确定,默认名称是settings.gradle。
settings 文件在初始化阶段执行,多项目构建必须在settings.gradle定义项目层次结构。这是必需的,因为文件定义了哪些项目参与了多项目构建。对于单项目构建,设置文件是可选的。
声明实例化和配置Project参与构建的实例层次结构所需的配置。
Settings实例和settings.gradle文件之间存在一一对应的关系。在 Gradle 构建项目之前,会创建一个 Settings实例。
Settings实例的属性如下图:

Settings实例的方法如下图:


gradle在生命周期三个阶段都设置了相应的钩子函数调用。

//settings.gradle
gradle.beforeSettings {
//Gradle.buildStarted()在6.0中弃用,7.0中彻底删除,采用beforeSettings替代
println '在settings加载之前执行,但是这个函数又放在了settings中,所以不会执行'
}
gradle.settingsEvaluated {
println 'settings脚本执行完成之后调用'
}
//每个module的build.gradle执行之前都会调用,闭包会传入当前的project对象作为参数
gradle.projectsLoaded {
println "所有的project对象加载完成"
}
//上述的写法也可以采用如下方式书写
gradle.addBuildListener(new BuildListener() {
@Override
void beforeSettings(Settings settings) {
super.beforeSettings(settings)
}
@Override
void settingsEvaluated(Settings settings) {}
@Override
void projectsLoaded(Gradle gradle) {}
})

//settings.gradle
//每个module的build.gradle执行之前都会调用,闭包会传入当前的project对象作为参数
//注意:如果在build.gradle中书写project.beforeProject闭包并不会执行(子模块的情况另说),参照gradle.beforeSettings函数
gradle.beforeProject{ project ->
println 'beforeProject $project'
}
gradle.afterProject{ project ->
println 'afterProject $project'
}
//所有module的build.gradle脚本执行完成之后,表示build.gradle执行完成
gradle.projectsEvaluated {
println 'projectsEvaluated'
}
// task有向无环图构建完成,配置阶段完成,TaskExecutionGraph对象作为对象传入闭包
gradle.taskGraph.whenReady { graph ->
println 'whenReady'
}
// 同gradle.taskGraph.whenReady
gradle.addListener(new TaskExecutionGraphListener() {
@Override
void graphPopulated(TaskExecutionGraph taskExecutionGraph) {
println "TaskExecutionGraphListener.graphPopulated"
}
})
//project.beforeEvaluate的执行时机
public class DemoPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.beforeEvaluate {
println("beforeEvaluate")
}
}
}
//如果这个DemoPlugin是被写在`build.gradle`文件里,像这样`apply plugin: 'demoPlugin'`,`beforeEvaluate()`方法不会执行,而如果是在rootPlugin里,调用subProject的`apply plugin 'demoPlugin'`,则`beforeEvaluate()`会被执行。原因是`beforeEvaluate()`这个方法是在解析`build.gradle`文件之前执行,在`build.gradle`中才注册`beforeEvaluate()`监听方法,已经晚了。
基于此,我们想在解析`build.gradle`之前,改变`build.gradle`文件的内容,可以在
beforeEvaluate() 这个方法里修改`build.gradle`。

//settings.gradle
gradle.taskGraph.beforeTask {
//7.3已过时,8.0中将删除
}
gradle.taskGraph.afterTask {
//7.3已过时,8.0中将删除
}
//或者如下写法
gradle.addListener(new TaskActionListener() {
@Override
void beforeActions(Task task) {
}
@Override
void afterActions(Task task) {
}
})