一、Gradle构建生命周期概述
在gradle官方文档的介绍中可以看到Gradle构建生命周期主要分为三个核心阶段:(链接:docs.gradle.org/current/use…
- 初始化阶段(Initialization Phase)
- 初始化构建脚本环境。
- 加载
settings.gradle(.kts)文件以确定构建范围(包括哪些子项目将参与构建)。 - 创建
Project对象树,并为每个项目加载其对应的build.gradle(.kts)配置文件。
- 配置阶段(Configuration Phase)
- 遍历所有项目的构建脚本并解析其中的DSL语句。
- 定义并配置所有的Task实例,包括内置任务和自定义任务。
- 解析并注册依赖管理信息,包括项目的依赖和传递性依赖。
- 执行阶段(Execution Phase)
- 在此阶段,Gradle按照特定顺序执行各个任务。
二、生命周期钩子与定制化构建
Gradle提供了丰富的生命周期钩子,允许开发者在不同阶段插入自定义逻辑。例如:
beforeEvaluate和afterEvaluate:在项目配置开始前和结束后执行。doFirst和doLast:在每个任务执行前后运行代码块。tasks.whenTaskAdded:当新任务被添加到构建时触发。
通过这些钩子,我们可以动态修改配置、改变任务行为或者添加新的功能,以适应项目的特性和需求。
Groovy
task myTask {
doLast {
println "task myTask doLast"
}
println "task myTask configuration"
doFirst {
println "task myTask doFirst"
}
}
project.afterEvaluate {
println "project afterEvaluate"
}
beforeEvaluate {
println "project beforeEvaluate"
}
tasks.whenTaskAdded { task ->
if (task.name == 'assembleDebug') {
println "A new task named '${task.name}' has been added."
task.dependsOn 'myTask'
}
}
执行 ./gradlew -q myTask 输出结果如下:
task myTask configuration
A new task named 'assembleDebug' has been added.
project afterEvaluate
task myTask doFirst
task myTask doLast
可以看到task闭包中"println "task myTask configuration" 这行代码执行在配置阶段,"project.afterEvaluate"在配置阶段完成后执行,"project beforeEvaluate"没有打印是因为beforeEvaluate发生在配置之前,初始化阶段之后,由于我们的命令并不会执行初始化所以没有打印。
"assembleDebug"是AGP中的task,whenTaskAdded当一个新的任务被创建并添加到当前项目时,这个钩子就会被执行,并且执行在project afterEvaluate之前,可见也是在配置阶段。
doFirst和doLast发生在执行阶段,它们允许你在任务执行之前或之后添加自定义的操作步骤。
上面的示例whenTaskAdded中我们使用了dependsOn,dependsOn 是一个用于定义任务依赖关系的关键字。当一个任务声明它 dependsOn 另一个或多个任务时,这意味着:
- 执行顺序: 在执行当前任务之前,Gradle会确保所有被依赖的任务已经先完成。也就是说,如果你有一个任务A,它
dependsOn任务B和任务C,那么在执行任务A之前,Gradle会先执行任务B,接着执行任务C,最后才执行任务A。 - 构建逻辑: 通过这种方式,可以控制项目构建的逻辑流,确保按正确的顺序编译、测试、打包、部署等操作。
这里我们此时执行 ./gradlew -q assembleDebug 就会在执行assembleDebug任务之前先执行myTask
三、实战应用场景
深入了解Gradle构建生命周期有助于我们更好地优化以下方面:
- 自动化流程设计:结合Jenkins等CI/CD工具,根据构建阶段触发不同的自动化操作,如测试报告发布、制品上传等。
- 插件开发:编写自定义插件时,可以准确地在合适的时间点注入自己的逻辑,确保与其他任务无缝集成。例如在mergeAssets之后对assets中的文件进行加密等等