- 生命周期中的这些钩子函数都是由 gradle 自动回调完成的,利用这些钩子函数可以帮助我们实现一些我们想要的功能

| |
| 1.在 settings.gradle 执行完后,会回调 Gradle 对象的 settingsEvaluated 方法 |
| 2.在构建所有工程 build.gradle 对应的 Project 对象后,也既初始化阶段完毕,会回调 Gradle 对象的 projectsLoaded 方法 |
| |
| |
| 1.Gradle 会循环执行每个工程的 build.gradle 脚本文件 |
| 2.在执行当前工程 build.gradle 前,会回调 Gradle 对象的 beforeProject 方法和当前 Project 对象的 beforeEvaluate 方法, 虽然 beforeEvalute 属于 project 的生命周期, 但是此时 build script 尚未被加载, 所以 beforeEvaluate 的设置依 |
| 然要在 init script 或 setting script 中进行,不要在 build script 中使用 project.beforeEvaluate 方法。 |
| 3.在执行当前工程 build.gradle 后,会回调 Gradle 对象的 afterProject 方法和当前 Project 对象的 afterEvaluate 方法 |
| 4.在所有工程的 build.gradle 执行完毕后,会回调 Gradle 对象的 projectsEvaluated 方法 |
| 5.在构建 Task 依赖有向无环图后,也就是配置阶段完毕,会回调 TaskExecutionGraph 对象的 whenReady 方法 |
| |
| |
| 1.Gradle 会循环执行 Task 及其依赖的 Task |
| 2.在当前 Task 执行之前,会回调 TaskExecutionGraph 对象的 beforeTask 方法 |
| 3.在当前 Task 执行之后,会回调 TaskExecutionGraph 对象的 afterTask |
| |
| 当所有的 Task 执行完毕后,会回调 Gradle 对象的 buildFinish 方法 |
| Gradle 执行脚本文件的时候会生成对应的实例,主要有如下几种对象 |
| 1、Gradle 对象:在项目初始化时构建,全局单例存在,只有这一个对象 |
| 2、Project 对象:每一个build.gradle文件 都会转换成一个 Project 对象,类似于maven中的pom.xml文件 |
| 3、Settings 对象:settings.gradle 会转变成一个 settings 对象,和整个项目是一对一的关系,一般只用到include方法 |
| 4、Task对象: 从前面的有向无环图中,我们也可以看出,gradle最终是基于Task的,一个项目可以有一个或者多个Task |
- 代码演示,在如下项目中演示

| # 在 root project 的 settings.gradle中添加如下 |
| gradle.settingsEvaluated { |
| println "settingsEvaluated" |
| } |
| gradle.projectsLoaded { |
| println "projectsLoaded" |
| } |
| |
| |
| def projectName="" |
| gradle.addProjectEvaluationListener( new ProjectEvaluationListener(){ |
| |
| @Override |
| void beforeEvaluate(Project project) { |
| projectName=project.name |
| println "${project.name} Project beforeEvaluate" |
| } |
| |
| @Override |
| void afterEvaluate(Project project, ProjectState projectState) { |
| println "${project.name} Project afterEvaluate" |
| } |
| }); |
| gradle.beforeProject { |
| println "${projectName} beforeProject..." |
| } |
| gradle.afterProject { |
| println "${projectName} afterProject..." |
| } |
| |
| def rootProjectName=rootProject.getName() |
| gradle.projectsEvaluated { |
| println "${rootProjectName} projectsEvaluated..." |
| } |
| |
| gradle.taskGraph.whenReady { |
| println "${rootProjectName} taskGraph whenReady..." |
| } |
| |
| gradle.taskGraph.beforeTask {task -> |
| println "this is the task ${task.name} of the project ${task.getProject().name} beforeTask.." |
| } |
| |
| gradle.taskGraph.afterTask {task -> |
| println "this is the task ${task.name} of the project ${task.getProject().name} afterTask.." |
| } |
| |
| gradle.buildFinished { |
| println "${rootProjectName} buildFinished..." |
| } |
| |
| # 在 root 的 build.gradle 文件中添加如下 |
| task A { |
| println "root taskA" doFirst(){ |
| println "root taskA doFirst" |
| } |
| doLast(){ |
| println "root taskA doLast" |
| } |
| } |
| |
| # 在 subject01 的 build.gradle 文件中添加如下 |
| task B { |
| println "SubProject01 taskB" doFirst(){ |
| println "SubProject01 taskB doFirst" |
| } |
| doLast(){ |
| println "SubProject01 taskB doLast" |
| } |
| } |
| |
| # 在 subject02 的 build.gradle 文件中添加如下 |
| |
| task C{ |
| |
| dependsOn 'D' |
| println "SubProject02 taskC" |
| doFirst(){ |
| println "SubProject02 taskC doFirst" |
| } |
| doLast(){ |
| println "SubProject02 taskC doLast" |
| } |
| } |
| |
| task D { |
| println "SubProject02 taskD" |
| doFirst(){ |
| println "SubProject02 taskD doFirst" |
| } |
| doLast(){ |
| println "SubProject02 taskD doLast" |
| } |
| } |
| |
| # 测试:在 root 工程的根目录执行:gradle C .就能看到 gradle 生命周期的三个阶段,及每个阶段执行的钩子函数、还有在执行阶段有依赖关系的任务的执行顺序问题。 |
- 计算 Gradle 构建过程中各个阶段的耗时:需要注意,这里只是计算了初始化阶段的 settings 文件,并没有计算init.gradle 初始化的时间
| # 在settings.gradle中编写如下 |
| def projectName=rootProject.getName() |
| long beginOfSetting = System.currentTimeMillis() |
| def beginOfConfig |
| def configHasBegin = false |
| def beginOfProjectConfig = new HashMap() |
| def beginOfTaskExecute |
| gradle.projectsLoaded { |
| println "${projectName}工程 初始化总耗时 ${System.currentTimeMillis() - beginOfSetting} ms" |
| } |
| |
| gradle.beforeProject {Project project -> |
| if(!configHasBegin){ |
| configHasBegin = true |
| beginOfConfig = System.currentTimeMillis() |
| } |
| beginOfProjectConfig.put(project,System.currentTimeMillis()) |
| } |
| |
| gradle.afterProject {Project project -> |
| def begin = beginOfProjectConfig.get(project) |
| if(project.name == projectName) { |
| println "根工程${projectName} 配置阶段耗时:${System.currentTimeMillis() - begin} ms" |
| }else{ |
| println "子工程${project.name} 配置阶段耗时:${System.currentTimeMillis() - begin} ms" |
| } |
| } |
| gradle.taskGraph.whenReady { |
| println "整个${projectName}项目在配置阶段总耗时:${System.currentTimeMillis() - beginOfConfig} ms" |
| beginOfTaskExecute = System.currentTimeMillis() |
| } |
| |
| gradle.taskGraph.beforeTask {Task task -> |
| task.doFirst { |
| task.ext.beginOfTask = System.currentTimeMillis() |
| } |
| task.doLast { |
| println "${task.name}在执行阶段耗时:${System.currentTimeMillis() - task.ext.beginOfTask} ms" |
| } |
| } |
| gradle.buildFinished { |
| println " 执行阶段总耗时:${System.currentTimeMillis() - beginOfTaskExecute} ms" |
| println " 整个构建过程耗时:${System.currentTimeMillis() - beginOfSetting} ms" |
| } |
| |
| # 删除根工程的task A和subject01子模块的task B |
| # 测试:gradle build |
- 在 settings.gradle 中添加监听器,查看 task 有向无环图
| gradle.taskGraph.addTaskExecutionGraphListener(new TaskExecutionGraphListener() { |
| @Override |
| void graphPopulated(TaskExecutionGraph taskExecutionGraph) { |
| taskExecutionGraph.allTasks.forEach(task->{ |
| taskExecutionGraph.allTasks.forEach(releaseTask->{ |
| println "尚硅谷:" + releaseTask.getProject().name + ":" + releaseTask.name }) |
| }) |
| } |
| }) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术