两个重要的概念

项目

实际上,一个项目是什么取决于你要用 Gradle 做什么?项目通常代表的是构建内容。 例如在 Android 中,一个 module 就是一个项目;

  • 项目是注册在 settings.gradle 中的
  • 通常一个项目有一个 build.gradle

Gradle 构建就是由一个或多个项目组成的。

任务

任务 顾名思义就是一个在构建阶段被执行的操作。它是 Gradle 构建的原子工作单位。例如 编译 Java 源代码;

任务是定义在项目的构建脚本中,并且可以彼此依赖。

一个项目就是由一个个任务组成的。

每一个 Gradle 构建都会按照相同的顺序经历三个不同的阶段:

初始化

Gradle 支持单项目构建和多项目构建。

在这个阶段 Gradle 会确认哪些项目将会参与构建。Gradle 会通过 settings.gradle 确定是多项目还是单项目构建。

Gradle 会为每个项目创建 Project 实例。

配置

在这个阶段执行在初始化阶段中确定的每一个项目的配置脚本,但是并不会执行其中的任务,只会评估任务的依赖性,根据其依赖性创建任务的有向无环图。

Gradle引入了一个称为随需求变配置的特性,该特性使它能够在构建过程中只配置相关和必要的项目。这在大型多项目构建中非常有用,因为它可以大大减少构建时间。

执行

在这个阶段,Gradle 会识别在配置阶段创建的任务的有向无环图。并按照他们的依赖顺序开始执行。

所有的构建工作都是在这个阶段执行的。如编译源码,生成 .class 文件,复制文件等。

settings.gradle

这个文件是由 Gradle 约定命名的,默认名为 settings.gradle ,在初始化阶段被执行。

对于多项目构建,必须在这里声明要参与构建的所有项目。对于单项目构建就是可选的了,可有可无。

Gradle 是如何寻找 settings.gradle 的?

  1. 在当前目录寻找
  2. 没有找到的话就去父目录寻找
  3. 仍然没有找到就是是单项目构建了
  4. 如果找到了就是确定其中的项目,如果当前执行的项目在 settings.gradle 有定义就执行多项目构建,否则就执行单项目构建。

一个脚本的属性访问和方法调用是委托给 Project 类的实例的,类似的 settings.gradle 的属性访问和方法调用是委托给 Settings 类的实例对象的。

单项目构建

对于单项目构建,在初始化后的工作流程很简单,构建脚本针对初始化阶段创建的项目对象执行。查找在命令行传入的任务名称相同的任务。

如果任务存在则作为一个单独的构建按照命令行传递的顺序执行。

多项目构建

多项目构建是在 Gradle 的单个执行过程中构建多个项目的构建。必须把参与构建的项目声明在 settings.gradle 里

项目位置

可以把多项目构建看作一个单根的树。每一个项目都是树上的一个节点。一个项目有一个路径表示在树中的位置。

通常情况下项目的路径和在文件系统中的位置是一致的,当然了这个路径也是可以配置的。

项目树是 settings.gradle 生成的,默认情况下 settings.gradle 的位置就是根项目的位置。但是你可以在 settings.gradle 文件中更改。

构建项目树

在 settings.gradle 设置文件中你可以使用一些列的方法配置构建项目树。分层和平面物理布局都支持。

分层布局

Groovy

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

Kotlin

include("project1", "project2:child", "project3:child1")

include 方法使用项目路径作为参数,假定项目路径与相对物理文件系统路径相等。

例如 "project2:child" 默认对应的是相对于根目录的 "project2/child"。

这也意味着包含路径 “services:hotels:api” 将创建3个项目:

  • “services”
  • “services:hotels”
  • “services:hotels:api”

更详细的说明可以 DSL文档

平面布局

Groovy

includeFlat 'project3', 'project4'

Kotlin

includeFlat("project3", "project4")

includeFlat 也是目录名字作为参数。这些目录要和根项目目录同级。

这些目录的位置在项目树中是根项目的子项目。

更改项目树的元素

在设置文件中创建的多项目树由所谓的项目描述符组成。这些项目符号可以随时更改。

可以通过下面这种方式访问描述符

查找项目树的元素

Groovy

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

Kotlin

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

使用这个描述符你可以一个项目的名字,项目目录和构建文件

更改项目树元素

Groovy

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

Kotlin

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

更详细的信息可以查看 ProjectDescriptor 类的 API 文档。

接收生命周期事件

构建脚本可以接收生命周期构建进度的通知。

接收这些通知一般是两种形式

  • 实现详细的监听接口
  • 在发送通知时提供一个闭包来执行

项目评估事件

可以在项目评估后马上接到事件通知 使用的是 Project.afterEvaluate 方法,传入一个闭包,Gradle会将评估的项目和状态传递进闭包里。

Kotlin

afterEvaluate {
println("${project.getName()} 评估结果:${state.getExecuted()}")
}

Groovy

afterEvaluate{ project,state->
println "$project 评估成功否:${state.failure==null}"
}

如果是在多项目构建里,可以在 allprojects 的闭包里使用,这样每个项目的评估事件就都接受到了

Groovy

allprojects{
afterEvaluate{ project,state->
println "$project 评估成功否:${state.failure==null}"
}
}

评估前的事件通知使用 Project.beforeEvaluate 照样是传入一个闭包,Gradle会将要评估的项目传递进闭包里

Groovy

allprojects{
afterEvaluate{ project,state->
println "$project 评估成功否:${state.failure==null}"
} beforeEvaluate { project ->
println "开始评估 $project"
} }

这里列出了使用的 api文档。

任务

任务被添加到项目

Groovy

tasks.whenTaskAdded { task ->
println "$task 被添加到项目了。"
}

Kotlin

tasks.whenTaskAdded {
extra["srcDir"] = "src/main/java"
} val a by tasks.registering println("source dir is ${a.get().extra["srcDir"]}")

有向无环图填充完毕

使用的是 TaskExecutionGraph.whenReady 方法

Groovy

gradle.taskGraph.whenReady{ graph->
println "任务图准备好了:\n"
graph.allTasks.each {
print "$it , "
}
}

任务执行

Groovy

task ok

task broken(dependsOn: ok) {
doLast {
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 API 的查询地址

文档参考

Gradle-构建生命周期的更多相关文章

  1. Gradle 庖丁解牛(构建生命周期核心托付对象创建源代码浅析)

    [工匠若水 http://blog.csdn.net/yanbober 未经同意严禁转载,请尊重作者劳动成果.私信联系我] 1 背景 上一篇<Gradle 庖丁解牛(构建源头源代码浅析)> ...

  2. 002-Apache Maven 构建生命周期

    Maven - 构建生命周期 什么是构建生命周期 构建生命周期是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序.这里的阶段是生命周期的一部分. 举例说明,一个典 ...

  3. Maven 使用了一个标准的目录结构和一个默认的构建生命周期。

    Maven 使用了一个标准的目录结构和一个默认的构建生命周期. 约定优于配置 当创建 Maven 工程时,Maven 会创建默认的工程结构.开发者只需要合理的放置文件,而在 pom.xml 中不再需要 ...

  4. Maven 构建生命周期

    构建生命周期是什么? 构建生命周期阶段的目标是执行顺序是一个良好定义的序列.这里使用一个例子,一个典型的 Maven 构建生命周期是由下列顺序的阶段: 阶段 处理 描述 准备资源 资源复制 资源复制可 ...

  5. Maven学习(十三)-----Maven 构建生命周期

    Maven 构建生命周期 构建生命周期是什么? 构建生命周期阶段的目标是执行顺序是一个良好定义的序列. 这里使用一个例子,一个典型的 Maven 构建生命周期是由下列顺序的阶段: 阶段 处理 描述 准 ...

  6. Java-Maven-Runoob:Maven构建生命周期

    ylbtech-Java-Maven-Runoob:Maven构建生命周期 1.返回顶部 1. Maven 构建生命周期 Maven 构建生命周期定义了一个项目构建跟发布的过程. 一个典型的 Mave ...

  7. Apache Maven(二):构建生命周期

    Maven 约定的目录结构 我要遵循Maven已经约定好的目录结构,才能让maven在自动构建过程中找到对应的资源进行构建处理.以下是maven约定的目录结构: 项目名称 |-- pom.xml :M ...

  8. Maven的构建生命周期理解

    以下引用官方的生命周期解释https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html: 一.构建生命 ...

  9. maven 学习---Maven构建生命周期

    构建生命周期是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序.这里的阶段是生命周期的一部分. 举例说明,一个典型的 Maven 构建生命周期是由以下几个阶段的序 ...

  10. Maven构建生命周期

    以下引用官方的生命周期解释https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html: 一.构建生命 ...

随机推荐

  1. 【CYH-02】noip2018数论模拟赛:赛后题解

    1.小奔的矩阵 2.大奔的方案 3.小奔与不等四边形 4.小奔的方案 当然本次比赛肯定难度不会仅限于此啦!后续还会--

  2. matlab考试重点详解

    此帖是根据期末考试复习重点补充完成, 由于使用word编辑引用图片和链接略有不便, 所以开此贴供复习及学习使用.侵删 复习要点 第一章 Matlab的基本概念,名称的来源,基本功能,帮助的使用方法 1 ...

  3. 个人永久性免费-Excel催化剂功能第51波-聚光灯功能,长宽工作表不看错位使用

    Excel的聚光灯功能,笔者是有点看不上,也曾经写文吐槽过这些类似的功能的实用性,但现实可能真的很多小白很需要,大家Excel水平参差不齐,大量的不规范做表习惯,致使此功能使用场景仍然非常广阔.很怀疑 ...

  4. CUDA编程学习笔记2

    第二章 cuda代码写在.cu/.cuh里面 cuda 7.0 / 9.0开始,NVCC就支持c++11 / 14里面绝大部分的语言特性了. Dim3 __host__ __device__ dim3 ...

  5. 使用nvm管理多个不同版本的nodeJS之安装成功nodeJs之后使用npm报错的问题

    使用nvm安装nodeJS之后,node -v命令可以正常使用,但是npm命令一直报“npm不是内部命令”的错误,深入研究之后得到以下解决方案: 搭建步骤: (1)下载nvm   https://gi ...

  6. [leetcode] 11. Container With Most Water (medium)

    原题链接 以Y坐标长度作为木桶边界,以X坐标差为桶底,找出可装多少水. 思路: 前后遍历. Runtime: 5 ms, faster than 95.28% of Java class Soluti ...

  7. [OpenGL] 绘制并且判断凹凸多边形、自相交多边形。

    #include <iostream> #include <ctime> #include <GL/glut.h> #include <math.h> ...

  8. Git 安装及使用指南

    1 简介1.1 Git1.2 Github2 Git 在 Windows 下的安装和使用2.1 msysgit2.2 Tortoisegit2.2.1 安装2.2.2 配置2.2.3 简单使用 1 简 ...

  9. 基于Bitnami gitlab OVA包的gitlab 环境搭建

    前言 最近在折腾gitlab,本篇记录搭建的过程方便以后查找 环境 Windows server + VMware 安装 为方便本次我们直接采用Bitnami的VOA安装包(VOA格式可同时兼容Vir ...

  10. 从后端到前端之Vue(三)小结以及一颗真实的大树

    上一篇写了一下tab,下面整理一下用过的知识点,本想按照官网的文档,整理一下可以更清晰,结果也许是我的方法不对吧,总之更模糊了. 按照官网文档的顺序整理到了表单输入绑定之前,因为之前大致也就只涉及到这 ...