Gradle 的生命周期是它最核心的设计灵魂。无论你的项目有多大、配置有多复杂,Gradle 每次执行时都雷打不动地走完三个阶段 :初始化阶段(Initialization) 、配置阶段(Configuration) 和 执行阶段(Execution) 。
理解了这三个阶段,就能排查各种 Gradle 奇葩报错、优化编译速度。
1️⃣ 第一阶段:初始化阶段(Initialization)
核心任务:确定"谁"参与这次构建。
在这个阶段,Gradle 并不关心你的代码和依赖,它要找的是项目根目录下的 settings.gradle (或 settings.gradle.kts ) 文件。
- 它是怎么工作的?
Gradle 会读取 settings.gradle,看看里面通过 include 引入了哪些模块(Module)。如果是多项目/多模块构建,它会为每个模块创建对应的 Project 实例(在 Gradle 内部,一个模块就是一个 Project 对象)。
- 这个阶段会执行什么代码?
settings.gradle 文件里的所有代码都是在这个阶段执行的。
php
// settings.gradle
pluginManagement { ... } // 确定插件从哪些maven仓库下载
dependencyResolutionManagement { ... } // 统一仓库 + 加载Version Catalog
include ':app' // 告诉 Gradle:app 模块要参与初始化
include ':core' // 告诉 Gradle:core 模块也要参与
println "===== 初始化阶段结束 ====="
2️⃣ 第二阶段:配置阶段(Configuration)
核心任务:下载依赖、解析配置、画出"施工图纸"。
这是最容易让人产生误解的一个阶段。在配置阶段,Gradle 并没有开始编译代码!
- 它是怎么工作的?
Gradle 会自上而下执行每一个 build.gradle 里的代码。解析plugins{},dependencies{}, android{} 等DSL,最终目标是配置好所有的 Task(任务),并根据 Task 之间的依赖关系,在内存中构建出一张有向无环图 ( DAG , Directed Acyclic Graph ) 。它的这张图就是稍后执行阶段的"施工图纸"。
- 🚨 核心大坑:
因为配置阶段会执行 build.gradle 里的顶层代码,如果你把一些耗时的、属于执行阶段的代码 误写在了配置阶段,那么无论你执行什么 Gradle 命令,甚至只是执行一个最简单的 ./gradlew clean ,这段耗时代码都会被强行执行一遍!
❌ 错误示范:
arduino
// app/build.gradle
android { ... }
dependencies {
implementation '...'
}
// 这是一个自定义 Task
task myCustomTask {
// ⚠️ 注意:这里的代码直接暴露在 Task 外面,属于【配置阶段】执行!// 即使你今天只想运行 assembleDebug,下面这段计算也会被强行执行
println "正在计算复杂的配置..."
Thread.sleep(5000) // 恐怖!每次点编译都要无故卡 5 秒
}
正确示范:
arduino
task myCustomTask {
// 只有包在 doLast 闭包里的代码,才属于【执行阶段】
doLast {
println "只有当你真正调用 ./gradlew myCustomTask 时,我才会执行!"
}
}
3️⃣ 第三阶段:执行阶段(Execution)
核心任务:真正开始干活,加工、组装零件。
有了第二阶段画好的"施工图纸"(DAG 依赖图),Gradle 终于开始动手了。
- 它是怎么工作的?
Gradle 会盯着你在命令行里输入的最终目标(比如 ./gradlew assembleDebug),然后顺着依赖图,只执行与这个目标相关的 Task。叶子节点先执行,根节点最后执行。支持并行(无依赖的节点)
-
在这个阶段,才会发生真正的:
compileDebugKotlin/compileDebugJava(【编译】代码)mergeDebugResources(合并资源)minifyDebugWithR8(代码混淆)packageDebug(【打包】成 APK)
-
特点: 只有在配置阶段被标记为需要执行的 Task,且其内部包裹在
doFirst或doLast闭包里的代码,才会在这个阶段被依次调度执行。
💡 调优技巧
如果你想看你的项目里,这三个阶段各自花了多少时间,以便排查是谁拖慢了编译速度,你可以在项目根目录下执行:
bash
./gradlew assembleDebug --scan
或者在控制台的 Build -> Build Analyzer 里面查看,它会清晰地用图表告诉你:配置阶段花了多少秒,执行阶段又是哪个 Task 在当"时间小偷"。