Gradle 1.12用户指南翻译——第五十五章. 构建的生命周期

简介: 其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上的地址:https://github.com/msdx/gradledoc本文翻译所在分支:https://github.com/msdx/gradledoc/tree/1.12。
其他章节的翻译请参见:
http://blog.csdn.net/column/details/gradle-translation.html
翻译项目请关注Github上的地址:
https://github.com/msdx/gradledoc
本文翻译所在分支:
https://github.com/msdx/gradledoc/tree/1.12。
直接浏览双语版的文档请访问:
http://gradledoc.qiniudn.com/1.12/userguide/userguide.html。
另外,Android 手机用户可通过我写的一个程序浏览文档,带缓存功能的,目前0.5版本兼容 Android 2.3以上系统,项目地址如下:
https://github.com/msdx/gradle-doc-apk
翻译不易,转载请注明本文在CSDN博客上的出处:
http://blog.csdn.net/maosidiaoxian/article/details/60323351

关于我对Gradle的翻译,以Github上的项目及http://gradledoc.qiniudn.com 上的文档为准。如发现翻译有误的地方,将首先在以上两个地方更新。因时间精力问题,博客中发表的译文基本不会同步修改。

另外,目前Gradle1.12版本的文档进入校稿阶段,校稿的方式可以为到该项目https://github.com/msdx/gradledoc 提交issue或是pull request。校稿的结果不只是在此版本更新,也会用于改善Gradle下一版本(2.0)文档的翻译。


第五十五章. 构建的生命周期

我们之前说,Gradle 的核心是一种以依赖为基础进行编程的语言。用 Gradle 的话说,这意味着您可以定义任务和任务之间的依赖。Gradle 保证这些任务按照它们的依赖关系的顺序进行执行,并且每个任务都只执行一次。这些任务形成一个有向无环图。有许多构建工具在它们执行任务时生成了依赖关系图。Gradle 则在所有任务执行之前生成这这个完整的依赖关系图。这是 Gradle 的核心,它使得很多事情由不可能变得可能。

你的构建脚本能配置这个依赖关系图。因此严格来说,它们都是构建配置脚本

55.1. 构建阶段

一个 Gradle 构建具有三个明显的阶段。

初始化

Gradle 支持单项目及多项目的构建。在初始化阶段,Gradle 确定哪些项目是需要构建的,并为每个需要构建的项目创建一个Project实例。

配置

在这一阶段,对project对象进行配置。属于构建的所有 projects 的构建脚本都会被执行。Gradle 1.4 引入了一个孵化中的选择性加入的功能,叫configuration on demand。在此模式下,Gradle 只配置相关的项目(见第 56.1.1.1 节,“Configuration on demand")。

执行

Gradle 确定在配置阶段中,创建和配置的要被执行的任务的子集。这个子集是由传递给gradle命令的任务名称参数和当前目录所决定的。然后 Gradle 执行每个选定的任务。

55.2. 设置文件

在构建脚本文件旁边,Gradle 定义了一个设置文件。这个设置文件是由 Gradle 通过一种命名约定来决定的。它的默认名称是settings.gradle。在本章后面,我们会解释 Gradle 是怎么查找一个设置文件的。

这个配置文件会在初始化阶段执行。一个多项目的构建,必须在这个多项目的层次结构中的根目录下有一个settings.gradle 文件。因为在这个设置文件中,会定义哪些项目会加入这个多项目构建(见第56章,多项目构建)。对于单项目的构建,有没有设置文件都可以。你可能需要一个关于将libraries添加到你的构建脚本类路径中的例子(见第59章,组织构建逻辑)。我们先来看一个一个单项目构建:

示例 55.1. 单项目构建

settings.gradle

println 'This is executed during the initialization phase.'

build.gradle

println 'This is executed during the configuration phase.'

task configured {
    println 'This is also executed during the configuration phase.'
}

task test << {
    println 'This is executed during the execution phase.'
}

gradle test 的输出结果

> gradle test
This is executed during the initialization phase.
This is executed during the configuration phase.
This is also executed during the configuration phase.
:test
This is executed during the execution phase.

BUILD SUCCESSFUL

Total time: 1 secs

对于一个构建脚本,属性的访问和方法的调用会委派给一个project对象。同样,在设置文件中的属性访问和方法调用也会委托给一个settings 对象。可以看一下 Settings

55.3. 多项目构建

多项目构建是指在一次Gradle执行中,构建多个项目。你需要在settings文件中,声明要加入多项目构建的项目。关于多项目构建,在这一主题的章节中有更多的介绍(参见 第 56 章, 多项目构建)。

55.3.1. 项目位置

多项目构建总是由一个具有单个根节点的树表示。树中的每个元素表示一个项目。一个项目有一个路径,表示在多项目构建树中的位置。在大多数情况下,项目路径是符合在文件系统中项目的物理位置的。不过,这种行为是可配置的。项目树在settings.gradle文件中创建。默认情况下,它假设设置文件的位置也是根项目的位置。但你可以在设置文件中重新定义根项目的位置。

55.3.2. 生成树

在设置文件中你可以使用一套方法来生成项目树。分层和产面的物理布局,得到了特别的支持。

55.3.2.1. 分层布局

示例 55.2. 分层布局

settings.gradle

include 'project1', 'project2:child', 'project3:child1'

include方法采用项目路径作为参数。项目路径被假定为等于物理文件系统的相对路径。例如,一个路径 'services:api',默认情况下映射到文件夹'services/api'(相对于项目根目录)。你只需要指定树上的叶子。这意味着,包含路径 'services:hotels:api' 将导致创建3个项目: 'services'、'services:hotels'和'services:hotels:api'。

55.3.2.2. 平面布局

示例 55.3. 平面布局

settings.gradle

includeFlat 'project3', 'project4'

includeFlat方法将目录名称作为参数。这些目录必须存在,并且与根项目目录同级。这些目录的位置被认为是多项目树中根项目的子项目。

55.3.3. 修改项目树元素

在设置文件中创建的多项目树组成了所谓的项目描述符。你可以在任何时间修改设置文件中的这些描述符。你可以这样访问一个描述符:

示例 55.4. 修改项目树中的元素

settings.gradle

println rootProject.name
println project(':projectA').name

使用这个描述符,你可以更改一个项目的名称、项目目录和构建文件。

示例 55.5. 修改项目树中的元素

settings.gradle

rootProject.name = 'main'
project(':projectA').projectDir = new File(settingsDir, '../my-project-a')
project(':projectA').buildFileName = 'projectA.gradle'

更多信息请参阅ProjectDescriptor

55.4. 初始化

Gradle 是怎么知道这是单项目还是多项目构建的?如果你在一个有设置文件的目录中触发一个多项目构建,那很简单。但 Gradle 也允许你在属于这个构建的任何子项目中去执行构建。[20]如果你在没有settings.gradle文件的项目中执行从 Gradle,Gradle 将执行以下操作︰

  • 它将在一个与当前目录有相同嵌套层的叫做master的目录里面搜索settings.gradle

  • 如果没有找到settings.gradle,它将在父目录里搜索settings.gradle文件。

  • 如果仍没有找到settings.gradle文件,将作为一个单项目构建来执行。

  • 如果找到了settings.gradle文件,Gradle 会检查当前项目是否为找到的settings.gradle文件中定义的多项目层次结构的一部分。如果不是,构建将作为一个单项目构建来执行。否则执行多项目构建。

这种行为的目的是什么?由于一些不明的原因, Gradle 不得不找出,你所进入的项目,它是否为一个多项目构建中的一个子项目。当然,如果它是一个子项目,那么就只构建子项目和它依赖的项目。但 Gradle 需要创建整个多项目构建的构建配置(见第56章,多项目生成)。通过-u命令行选项,你可以让 Gradle 不去父目录找settings.gradle文件。那么,当前项目将只会作为单项目构建。如果当前项目中包含一个settings.gradle文件, -u选项将没有任何意义。这样的构建总是这样执行:

  • 单项目构建,如果settings.gradle文件没有定义一个多项目的层次结构

  • 多项目构建,如果settings.gradle文件定义了一个多项目的层次结构。

自动搜索设置文件只适合具有物理上的层次结构或平面的布局的多项目构建。对于平面布局你必须另外服从上面描述的命名约定。Gradle 支持任意的物理布局的多项目构建。但对于这种任意的布局,你需要在设置文件所在的目录执行构建。有关如何从根目录运行部分的构建,见第 56.4章,“使用其绝对路径运行任务”。在我们下一版本中,我们想通过在命令行参数中,指定一个设置文件的路径,来从子项目中启用部分的构建。在构建中,Gradle 为每个参加构建的项目创建 Project 对象。对于单项目构建,只有一个project。对于多项目构建,则有在 Setting 对象中指定的project(加上根项目的project)。每个project 对象都有和其顶层目录名称一样的默认名称。除了根 project,每个project有一个父project,并且可能还有子projects。

55.5. 配置和执行单个项目构建

对于一个单项目构建,初始化后阶段的工作流都相当简单。构建脚本会针对在初始化阶段期间创建的 project 对象执行。然后 Gradle 会查找与命令行传进来的参数相同的任务名。如果这些任务名称存在,它们以参数的顺序作为一个单独的构建来执行。关于多项目构建的配置与执行,在<a0>第 56 章,<i1>多项目构建</i1></a0>中有论述。

55.6. 构建脚本生命周期的响应

在构建通过其生命周期的时候,你的构建脚本会接收到对应的通知。这些通知一般采取两种形式︰你也可以实现一个特定的监听接口,或提供一个用于在收到通知时执行的闭包。下面是使用闭包的例子。有关如何使用监听器接口的详细信息,请参阅 API 文档。

55.6.1. 项目评估

你可以在一个项目评估之前及之后立刻收到通知。这可以用来做一些事情,比如一旦构建脚本里的定义都被应用时执行额外的配置,或者做一些自定义的日志记录或分析。

下面是一个示例,将一个test任务添加到每个hasTests属性为 true 的project中。

示例 55.6. 向每个包含某些属性设置的project 添加测试任务

build.gradle

allprojects {
    afterEvaluate { project ->
        if (project.hasTests) {
            println "Adding test task to $project"
            project.task('test') << {
                println "Running tests for $project"
            }
        }
    }
}

projectA.gradle

hasTests = true

gradle -q test的输出结果

> gradle -q test
Adding test task to project ':projectA'
Running tests for project ':projectA'

上面的例子使用了Project.afterEvaluate()方法添加一个在project 评估之后执行的闭包。

你也可以在每一个project 评估之后收到收到通知。下面的例子是在执行项目评估的自定义日志记录。注意,无论项目评估是成功还是由于异常而失败,都会收到afterProject通知。

示例 55.7. 通知

build.gradle

gradle.afterProject {project, projectState ->
    if (projectState.failure) {
        println "Evaluation of $project FAILED"
    } else {
        println "Evaluation of $project succeeded"
    }
}

gradle -q test的输出结果

> gradle -q test
Evaluation of root project 'buildProjectEvaluateEvents' succeeded
Evaluation of project ':projectA' succeeded
Evaluation of project ':projectB' FAILED

你也可以将一个ProjectEvaluationListener添加到Gradle中,来接收这些事件。

55.6.2. 任务创建

你可以在有任务添加到项目后立即收到通知。这可以用来在构建脚本中的任务可用之前,设置一些默认值或添加行为。

下面的示例是在每个任务创建之前设置srcDir属性。

示例 55.8. 对所有的任务设置一些属性

build.gradle

tasks.whenTaskAdded { task ->
    task.srcDir = 'src/main/java'
}

task a

println "source dir is $a.srcDir"

gradle -q a的输出结果

> gradle -q a
source dir is src/main/java

你还可以向TaskContainer添加一个Action来接收这些事件。

55.6.3. 任务执行图准备

在任务执行图生成之后你可以立刻收到一个通知。在第 6.13 章,“使用DAG配置”我们已经看到进了。

你也可以向TaskExecutionGraph添加一个TaskExecutionGraphListener来接收这些事件。

55.6.4. 任务执行

在任一任务执行前你都会马上收到一条通知。

下面的示例展示了在每个任务执行的开始及结束时打印日志。注意,无论任务成功完成还是异常失败,都会收到afterTask的通知。

示例55.9. 在每个任务执行的开始及结束时打印日志

build.gradle

task ok

task broken(dependsOn: ok) << {
    throw new RuntimeException('broken')
}

gradle.taskGraph.beforeTask { Task task ->
    println "executing $task ..."
}

gradle.taskGraph.afterTask { Task task, TaskState state ->
    if (state.failure) {
        println "FAILED"
    }
    else {
        println "done"
    }
}

gradle -q broken的输出结果

> gradle -q broken
executing task ':ok' ...
done
executing task ':broken' ...
FAILED

你也可以对TaskExecutionGraph使用一个TaskExecutionListener来接收这些事件。



[20Gradle 支持部分多项目构建(参见 第 56 章, 多项目建)。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6月前
|
存储 缓存 Java
《Gradle构建脚本的基本结构和语法》
《Gradle构建脚本的基本结构和语法》
86 0
|
1月前
|
Java 测试技术 API
云效流水线构建gradle项目失败提示gradle版本过低如何解决
云效(CloudEfficiency)是阿里云提供的一套软件研发效能平台,旨在通过工程效能、项目管理、质量保障等工具与服务,帮助企业提高软件研发的效率和质量。本合集是云效使用中可能遇到的一些常见问题及其答案的汇总。
33 0
|
6月前
|
缓存 Java Maven
深入理解Gradle构建系统的工作原理
深入理解Gradle构建系统的工作原理
165 0
|
8月前
|
设计模式 Java Android开发
基于Gradle的Spring源码下载及构建技巧
首先你的JDK需要升级到1.8以上版本。从Spring 3.0开始,Spring源码采用GitHub托管,不再提供官网下载链接。这里不做过多赘述,大家可自行去GitHub网站下载,我使用的版本下载链接为 https://github.com/spring-projects/spring-framework/archive/v5.0.2.RELEASE.zip ,下载完成后,解压源码包会看到如下图所示的文件目录。
160 0
|
11月前
|
编解码 前端开发 Java
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目02
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目02
66 0
|
11月前
|
IDE 前端开发 Java
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目01
Spring Boot-Spring Tool Suit + Gradle 构建第一个Spring Boot 项目01
71 0
|
6月前
|
SQL 人工智能 移动开发
Android Studio插件版本与Gradle 版本对应关系
Android Studio插件版本与Gradle 版本对应关系
Android Studio插件版本与Gradle 版本对应关系
|
7月前
|
存储 Java Android开发
Android 开发 - 充分利用Gradle
Android 开发 - 充分利用Gradle
112 2
|
缓存 Android开发
Android Studio中如何清理gradle缓存
Android Studio中如何清理gradle缓存