urlname
type
Post
password
SyncToConfluence
category
Android
date
Mar 2, 2025
slug
1b1d71d9-7cfe-4e04-848f-a9aa823cf0c3
icon
Button
catalog
summary
tags
Android
Gradle
学习笔记
cover
Status
BusyTime
Status 1
status
Published
上次我们详细讲解了 Gradle 各个文件的作用。今天我们将 理论与实战相结合,通过一个具体的例子,并结合日志输出,清晰地看到 Gradle 生命周期的每个阶段是如何启动、执行,以及各个 Gradle 文件是如何被处理的。

Gradle 生命周期的三大阶段

Gradle 的生命周期主要分为三个阶段:
  1. 初始化阶段 (Initialization Phase)
  1. 配置阶段 (Configuration Phase)
  1. 执行阶段 (Execution Phase)
下面,我们就逐一详细讲解每个阶段,并结合实战例子进行说明。

初始化阶段 (Initialization Phase):构建的“地基” (理论 + 实战)

主要任务:

初始化阶段是 Gradle 构建的第一个阶段,也是构建的“地基”。在这个阶段,Gradle 主要完成以下任务:
  • 确定构建项目 (Determine the project to build): Gradle 会根据你执行 Gradle 命令时指定的项目目录,找到 settings.gradle (或 settings.gradle.kts) 文件,并将其视为构建的根项目。
  • 初始化 Settings 对象 (Initialize the Settings object): Gradle 会解析 settings.gradle 文件,并创建 Settings 对象Settings 对象包含了关于整个构建项目的配置信息,例如项目名、根项目目录、包含的子项目等。
  • 构建项目结构 (Build the project structure): Gradle 会根据 settings.gradle 文件中的 include 声明,创建项目结构。
    • 每个 include 语句都会创建一个 Project 对象,代表一个模块或子项目。
    • 这些 Project 对象会形成一个树状结构,代表整个项目的模块组织结构。

关键文件和代码:

  • settings.gradle(.kts): 初始化阶段的核心文件。include 语句、pluginManagementdependencyResolutionManagement 代码块都在初始化阶段被解析和执行。

代码示例 (settings.gradle.kts):

  • 日志输出 (部分):
  • 分析:
    • 从日志输出可以看到,首先输出的是 Settings Gradle: Initialization Phase - Start,表明初始化阶段开始。
    • 接着,Settings Gradle: Module 'app' included 日志表明 include(":app") 语句被执行,app 模块被成功包含。
    • pluginManagement blockdependencyResolutionManagement block 的日志,则印证了这两个代码块在初始化阶段被解析和执行,用于配置插件和依赖版本管理。
    • 最后,Settings Gradle: Initialization Phase - End 日志表明 settings.gradle.kts 文件执行完毕,初始化阶段结束。

小结:

  • 初始化阶段是构建的起点,settings.gradle 文件是关键。
  • settings.gradle 中定义的项目结构和插件/依赖管理配置,会影响到后续的配置和执行阶段。
  • 如果你的项目结构有问题 (例如模块声明错误),或者 settings.gradle 文件配置错误,构建就会在初始化阶段失败。 因此,确保 settings.gradle 文件配置正确非常重要。
  • 初始化阶段执行速度很快,通常不会成为构建瓶颈。 但如果 settings.gradle 文件过于复杂,或者包含了耗时的操作 (不建议在 settings.gradle 中做耗时操作),可能会影响初始化阶段的性能。

配置阶段 (Configuration Phase):构建的“蓝图”

主要任务:

配置阶段是 Gradle 构建的核心阶段,也是构建的“蓝图”绘制阶段。在这个阶段,Gradle 主要完成以下任务:
  • 解析构建脚本 (Parse build scripts): Gradle 会解析项目中的所有 build.gradle (和 build.gradle.kts) 文件,包括 Project-level 和 Module-level 的 build.gradle 文件。
  • 配置 Project 对象 (Configure Project objects): Gradle 会根据 build.gradle 文件中的配置,配置每个 Project 对象。这包括:
    • 应用插件 (Apply plugins): 应用在 build.gradle 文件 plugins 代码块中声明的插件 (Module-level build.gradle 会应用插件,Project-level build.gradle 通常只声明插件,使用 apply false)。
    • 配置 Android 扩展 (Configure Android extensions): 如果应用了 Android Gradle 插件,Gradle 会配置 android 扩展,解析 android 代码块中的配置,例如 compileSdk, buildTypes, dependencies 等。
    • 配置 Task (Configure tasks): 插件和构建脚本会定义各种 Task (例如 compileDebugKotlin, assembleRelease, testDebugUnitTest 等)。在配置阶段,Gradle 会创建并配置这些 Task 对象,设置 Task 的属性、输入、输出、依赖关系等。
  • 构建 Task 执行图 (Build the Task execution graph): Gradle 会根据 Task 之间的依赖关系 (例如 taskA.dependsOn(taskB)), 构建一个 Task 执行图 (Task graph)。这个执行图描述了 Task 的执行顺序和依赖关系。Gradle 会根据执行图,确定哪些 Task 需要执行,以及它们之间的执行顺序。
notion image

关键文件和代码:

  • build.gradle (Project-level)build.gradle (Module-level): 配置阶段的核心文件。 插件应用、Android 配置、依赖声明、Task 定义等都在配置阶段被解析和执行。

代码示例:

  • Project-level build.gradle.kts:
  • Module-level app/build.gradle.kts:
  • 日志输出 (部分):
  • 分析:
    • 紧接着初始化阶段之后,日志输出 Project-level Gradle: Configuration Phase - Start,表明配置阶段开始。
    • Project-level build.gradle.ktsplugins, allprojects, subprojects 代码块的日志,印证了 Project-level 构建脚本在配置阶段被解析和执行,配置项目级别的插件声明和通用设置。
    • 随后,Module-level app/build.gradle.ktsConfiguration Phase - Start 日志出现,表明 Module-level 构建脚本开始执行。
    • Module-level build.gradle.ktsplugins, android, dependencies 代码块的日志,印证了 Module-level 构建脚本在配置阶段被解析和执行,配置模块级别的插件应用、Android 设置和依赖声明。
    • 关键: Module-level Gradle (app): lifecycleTask - Configuration Phase 日志表明,自定义 Task lifecycleTask 的配置代码在配置阶段被执行,但 doFirstdoLast 代码块并没有执行
    • 最后,Module-level app/build.gradle.ktsConfiguration Phase - End 日志表明配置阶段结束。

小结:

  • 配置阶段是 Gradle 构建的核心,build.gradle 文件是关键。
  • 在配置阶段,Gradle 会解析构建脚本,配置项目和模块,应用插件,声明依赖,并构建 Task 执行图。
  • 大多数构建错误 (例如配置错误、依赖冲突) 都会在配置阶段被检测到。 因此,仔细检查 build.gradle 文件配置非常重要。
  • 配置阶段的性能对整体构建速度影响很大。 复杂的构建脚本、过多的插件和依赖、以及不合理的 Task 依赖关系,都可能导致配置阶段耗时过长。
  • 理解配置阶段,可以帮助你更好地优化构建脚本,减少配置时间,并更有效地定制构建逻辑。 例如,你可以通过使用 Configuration Cache 来缓存配置信息,加快配置阶段速度 (Gradle 6.6+)。

执行阶段 (Execution Phase):构建的“执行”

执行顺序:

执行阶段是 Gradle 构建的最后一个阶段,也是构建的“执行”阶段。在这个阶段,Gradle 会根据配置阶段构建的 Task 执行图,执行需要执行的 Task。
  • 执行 Task (Execute tasks): Gradle 会按照 Task 执行图的顺序,逐个执行需要执行的 Task。 每个 Task 都会执行其 doFirstdoLast 代码块 (如果定义了的话)。
  • Task 执行逻辑 (Task execution logic): Task 的执行逻辑通常由插件或构建脚本定义。 例如:
    • Android Gradle 插件的 Task: 例如 compileDebugKotlin Task 会调用 Kotlin 编译器编译 Kotlin 代码,assembleRelease Task 会打包生成 Release APK。
    • 自定义 Task: 例如上面示例中的 lifecycleTask 会打印相应的日志信息。
  • 依赖下载和处理 (Dependency download and processing): 如果 Task 需要依赖外部库 (例如远程仓库依赖),Gradle 会在执行阶段下载这些依赖库。
  • 构建产物生成 (Build artifact generation): Task 执行完成后,会生成构建产物,例如编译后的 class 文件、APK 文件、AAR 文件、报告文件等。

关键文件和代码:

  • Task 代码 (定义在插件或 build.gradle 文件中): 执行阶段的核心是 Task 的执行。 Task 的代码决定了 Task 的具体执行逻辑。

代码示例:

  • Module-level app/build.gradle.kts - lifecycleTask 定义:
  • 日志输出 (部分):
  • 分析:
    • 在配置阶段日志之后,控制台输出 > Task :app:lifecycleTask,表明 Gradle 开始执行 app:lifecycleTask 这个 Task,执行阶段开始。
    • 紧接着,Module-level Gradle (app): lifecycleTask - Execution Phase - doFirstModule-level Gradle (app): lifecycleTask - Execution Phase - doLast 日志输出,印证了只有在执行阶段,Task 的 doFirstdoLast 代码块才会被执行。

小结:

  • 执行阶段是 Gradle 构建的最后阶段,也是实际执行构建操作的阶段。
  • 在执行阶段,Gradle 会按照 Task 执行图执行 Task,下载依赖,生成构建产物。
  • 大多数构建时间都消耗在执行阶段,特别是编译、打包、测试等 Task。 因此,优化执行阶段的性能是提升构建速度的关键。
  • 理解执行阶段,可以帮助你更好地分析构建耗时,找到性能瓶颈,并采取相应的优化措施。 例如,可以使用 Build Cache 来缓存 Task 的输出,避免重复执行相同的 Task。

Gradle 生命周期总结图

为了更清晰地理解 Gradle 生命周期,我绘制了一个简单的流程图:
  • 图解:
      1. 初始化阶段 (Initialization Phase): Gradle 首先确定要构建的项目,初始化 Settings 对象,并根据 settings.gradle 构建项目结构。
      1. 配置阶段 (Configuration Phase): Gradle 解析 build.gradle 脚本,配置 Project 对象和 Task 对象,并构建 Task 执行图。
      1. Task 执行图构建 (Task Execution Graph Built): 配置阶段的最后一步是构建 Task 执行图,确定 Task 的执行顺序和依赖关系。
      1. 执行阶段 (Execution Phase): Gradle 根据 Task 执行图,执行 Task,下载依赖,并生成构建产物。
      1. 构建完成 (Build Finished): 所有需要执行的 Task 都执行完毕,构建过程结束。
  • 贴一张官方的构建流程图:
notion image

最后:

  • Gradle 生命周期是 Gradle 构建的核心概念,理解它对于Android工程师至关重要。
  • 掌握了 Gradle 生命周期,就能更好地理解构建过程,解决构建问题,优化构建速度,并能更灵活地定制构建逻辑。
  • 在未来的博客中,我也会继续分享更多关于 Gradle 的高级技巧和实践经验,希望能与大家共同进步,成为真正的 Gradle 大师!
Gradle系列——Gradle基础语法与DSL详解Gradle系列——文件详解
Loading...