3.gradle生命周期

149 阅读3分钟

一、Gradle构建生命周期概述

在gradle官方文档的介绍中可以看到Gradle构建生命周期主要分为三个核心阶段:(链接:docs.gradle.org/current/use…

  1. 初始化阶段(Initialization Phase)
    • 初始化构建脚本环境。
    • 加载settings.gradle(.kts)文件以确定构建范围(包括哪些子项目将参与构建)。
    • 创建Project对象树,并为每个项目加载其对应的build.gradle(.kts)配置文件。
  2. 配置阶段(Configuration Phase)
    • 遍历所有项目的构建脚本并解析其中的DSL语句。
    • 定义并配置所有的Task实例,包括内置任务和自定义任务。
    • 解析并注册依赖管理信息,包括项目的依赖和传递性依赖。
  3. 执行阶段(Execution Phase)
    • 在此阶段,Gradle按照特定顺序执行各个任务。

二、生命周期钩子与定制化构建

Gradle提供了丰富的生命周期钩子,允许开发者在不同阶段插入自定义逻辑。例如:

  • beforeEvaluateafterEvaluate:在项目配置开始前和结束后执行。
  • doFirstdoLast:在每个任务执行前后运行代码块。
  • 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之前,可见也是在配置阶段。

doFirstdoLast发生在执行阶段,它们允许你在任务执行之前或之后添加自定义的操作步骤。

上面的示例whenTaskAdded中我们使用了dependsOndependsOn 是一个用于定义任务依赖关系的关键字。当一个任务声明它 dependsOn 另一个或多个任务时,这意味着:

  1. 执行顺序: 在执行当前任务之前,Gradle会确保所有被依赖的任务已经先完成。也就是说,如果你有一个任务A,它dependsOn 任务B和任务C,那么在执行任务A之前,Gradle会先执行任务B,接着执行任务C,最后才执行任务A。
  2. 构建逻辑: 通过这种方式,可以控制项目构建的逻辑流,确保按正确的顺序编译、测试、打包、部署等操作。

这里我们此时执行 ./gradlew -q assembleDebug 就会在执行assembleDebug任务之前先执行myTask

三、实战应用场景

深入了解Gradle构建生命周期有助于我们更好地优化以下方面:

  • 自动化流程设计:结合Jenkins等CI/CD工具,根据构建阶段触发不同的自动化操作,如测试报告发布、制品上传等。
  • 插件开发:编写自定义插件时,可以准确地在合适的时间点注入自己的逻辑,确保与其他任务无缝集成。例如在mergeAssets之后对assets中的文件进行加密等等