Gradle三阶段

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,且其内部包裹在 doFirstdoLast 闭包里的代码,才会在这个阶段被依次调度执行。

💡 调优技巧

如果你想看你的项目里,这三个阶段各自花了多少时间,以便排查是谁拖慢了编译速度,你可以在项目根目录下执行:

bash 复制代码
./gradlew assembleDebug --scan

或者在控制台的 Build -> Build Analyzer 里面查看,它会清晰地用图表告诉你:配置阶段花了多少秒,执行阶段又是哪个 Task 在当"时间小偷"。

相关推荐
morchalen2 小时前
安卓framework学习6:Contacts 联系人 APP 日志
android
KANGBboy2 小时前
java知识四(面向对象编程)
android·java·开发语言
AD钙奶-lalala5 小时前
Android Studio新建项目默认不使用Compose模版
android·ide·android studio
故渊at7 小时前
第一板块:Android 系统基石与运行原理 | 第二篇:Android 编译、打包与安装机制
android·系统架构·apk·打包·application·dalvik·android编译
故渊at7 小时前
第一板块:Android 系统基石与运行原理 | 第三篇:ART 与 Dalvik 运行时环境原理
android·对象模型·内存布局·运行原理·art·dalvik
私人珍藏库9 小时前
【Android】Wallcraft 3.62.0-最强4 K壁纸软件-解锁高级版
android·智能手机·app·工具·软件·多功能
GesLuck9 小时前
Node-RED企业微信发送—群文件
android·java·企业微信
whatever who cares9 小时前
android中fragment demo举例
android·java·开发语言
zhangphil9 小时前
Android将ImageView显示的图原样取出转换为Bitmap,Kotlin
android·kotlin