Gradle构建脚本,内部是基于 Groovy 的 DSL(领域特点语言),而Maven是基于XML的,Groovy相比XML更加简洁、灵活和强大。 Groovy 因为给 Java 开发人员提供了最大的透明度,对于Java开发人员来说门槛很低,所以Gradle的重点是Java项目。这篇不是介绍Groovy的文章,对于Gradle应该要了解一些Groovy的知识,比如闭包,在Gradle构建任务是就是经常用到的。建议在此之前先看完Groovy基础章节。好了,下面言归正传。

Gradle 里的任何东西都是基于这两个基础概念:

Projects 和 tasks

  • projects ( 项目 )
  • tasks ( 任务 )

每一个构建都是由一个或多个 projects 构成的. 一个 project 到底代表什么依赖于你想用 Gradle 做什么. 举个例子, 一个 project 可以代表一个 JAR 或者一个网页应用. 它也可能代表一个发布的 ZIP 压缩包, 这个 ZIP 可能是由许多其他项目的 JARs 构成的. 但是一个 project 不一定非要代表被构建的某个东西. 它可以代表一件**要做的事, 比如部署你的应用.

每一个 project 是由一个或多个 tasks 构成的. 一个 task 代表一些更加细化的构建. 可能是编译一些 classes, 创建一个 JAR, 生成 javadoc, 或者生成某个目录的压缩文件.

我们先来看看定义构建里的一些简单的 tasks.

一个 Task 包含若干 Action。所以,Task 有 doFirst 和 doLast 两个函数,用于添加需要最先执行的 Action 和需要和需要最后执行的 Action。Action 就是一个闭包。

1、定义tasks

task(hello) << {
println "hello"
} task(copy, type: Copy) {
from(file('srcDir'))
into(buildDir)
}

使用 strings 来定义任务的名字:

task('hello') <<
{
println "hello"
} task('copy', type: Copy) {
from(file('srcDir'))
into(buildDir)
}

Task 创建的时候可以指定 Type,通过 type: 名字表达。这是什么意思呢?其实就是告诉 Gradle,这个新建的 Task 对象会从哪个基类 Task 派生。比如,Gradle 本身提供了一些通用的 Task,最常见的有 Copy 任务。Copy 是 Gradle 中的一个类。当我们:task myTask(type:Copy)的时候,创建的 Task 就是一个 Copy Task。

另外一种语法形式

tasks.create(name: 'hello') << {
println "hello"
} tasks.create(name: 'copy', type: Copy) {
from(file('srcDir'))
into(buildDir)
}

这里实际上我们把任务加入到 tasks collection 中.

2、第一个构建脚本

task hello {
doLast {
println 'Hello world!'
}
}

在命令行里, 进入脚本所在的文件夹然后输入 gradle -q hello 来执行构建脚本。gradle 命令会在当前目录中查找一个叫 build.gradle 的文件. 我们称这个 build.gradle 文件为一个构建脚本 (build script), 但是严格来说它是一个构建配置脚本 (build configuration script). 这个脚本定义了一个 project 和它的 tasks.

补充一点命令里的 -q 是干什么的?

这个指南里绝大多说的例子会在命令里加入 -q. 代表 quite 模式. 它不会生成 Gradle 的日志信息 (log messages), 所以用户只能看到 tasks 的输出. 它使得的输出更加清晰. 你并不一定需要加入这个选项. 参考第 18 章, 日志的 Gradle 影响输出的详细信息.

上面的脚本等价于:

task hello << {
println 'Hello world!'
}

doLast 被替换成了 <<,二者是对等的。

3、在 Gradle 任务里使用 Groovy

例1

task upper << {
String someString = 'mY_nAmE'
println "Original: " + someString
println "Upper case: " + someString.toUpperCase()
}

gradle -q upper 命令的输出

> gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME

例2

task count << {
4.times { print "$it " }
}

gradle -q count 命令的输出

> gradle -q count
0 1 2 3

4、任务依赖

task taskX(dependsOn: 'taskY') << {
println 'taskX'
}
task taskY << {
println 'taskY'
}

gradle -q taskX 命令的输出

> gradle -q taskX
taskY
taskX

注意:taskX 到 taskY 的依赖在 taskY 被定义之前就已经声明了.任务声明的顺序对于依赖顺序没有影响。

 5、动态任务

3.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}

这里动态的创建了 task1, task2, task3

gradle -q task1 命令的输出

> gradle -q task1
I'm task number 1

6、使用已经存在的任务

  • 通过API访问一个任务 - 加入一个依赖
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
task0.dependsOn task2, task3
> gradle -q task0
I'm task number 2
I'm task number 3
I'm task number 0
  • 通过API访问一个任务 - 加入行为
task hello << {
println 'Hello Earth'
}
hello.doFirst {
println 'Hello Venus'
}
hello.doLast {
println 'Hello Mars'
}
hello << {
println 'Hello Jupiter'
}
> gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter

7、短标记法

有一个短标记 $ 可以访问一个存在的任务. 也就是说每个任务都可以作为构建脚本的属性:

task hello << {
println 'Hello world!'
}
hello.doLast {
println "Greetings from the $hello.name task."
}

这里的 name 是任务的默认属性, 代表当前任务的名称, 这里是 hello.

> gradle -q hello
Hello world!
Greetings from the hello task.

8、自定义任务属性

你可以给任务加入自定义的属性. 列如加入一个叫做 myProperty 属性, 设置一个初始值给 ext.myProperty. 然后, 该属性就可以像一个预定义的任务属性那样被读取和设置了.

task myTask {
ext.myProperty = "myValue"
} task printTaskProperties << {
println myTask.myProperty
}
> gradle -q printTaskProperties
myValue

9、调用 Ant 任务

Ant 任务是 Gradle 的一等公民. Gradle 通过 Groovy 出色的集成了 Ant 任务. Groovy 自带了一个 AntBuilder. 相比于从一个 build.xml 文件中使用 Ant 任务, 在 Gradle 里使用 Ant 任务更为方便和强大.

使用 AntBuilder 来执行 ant.loadfile 任务

task loadfile << {
def files = file('../antLoadfileResources').listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
}
> gradle -q loadfile
*** agile.manifesto.txt ***
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
*** gradle.manifesto.txt ***

10、定义默认任务

defaultTasks 'clean', 'run'

task clean << {
println 'Default Cleaning!'
} task run << {
println 'Default Running!'
} task other << {
println "I'm not a default task!"
}

gradle -q 命令的输出

> gradle -q
Default Cleaning!
Default Running!

11、通过 DAG 配置

Gradle 有一个配置阶段和执行阶段. 在配置阶段后, Gradle 将会知道应执行的所有任务. Gradle 为你提供一个”钩子”, 以便利用这些信息. 举个例子, 判断发布的任务是否在要被执行的任务当中. 根据这一点, 你可以给一些变量指定不同的值.

根据选择的任务产生不同的输出

task distribution << {
println "We build the zip with version=$version"
} task release(dependsOn: 'distribution') << {
println 'We release now'
} gradle.taskGraph.whenReady {taskGraph ->
if (taskGraph.hasTask(release)) {
version = '1.0'
} else {
version = '1.0-SNAPSHOT'
}
}

distribution 任务和 release 任务将根据变量的版本产生不同的值.

> gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
Output of gradle -q release
> gradle -q release
We build the zip with version=1.0
We release now

参考文章:Gradle 用户指南官方文档中文版

Gradle构建脚本基础的更多相关文章

  1. 【Gradle】Gradle构建脚本基础

    Gradle构建脚本基础 Settings文件 在Gradle中,定义了一个设置文件,用于初始化以及工程树的配置.设置文件的默认名为settings.gradle,放在根工程目录下. 设置文件大多数的 ...

  2. 【转载】Gradle学习 第六章:构建脚本基础

    转载地址:http://ask.android-studio.org/?/article/11 6.1. Projects and tasks 项目和任务Everything in Gradle si ...

  3. 读书笔记--Android Gradle权威指南(下)

    前言 最近看了一本书<Android Gradle 权威指南>,收获挺多,就想着来记录一些读书笔记,方便后续查阅. 本篇内容是基于上一篇:读书笔记--Android Gradle权威指南( ...

  4. 读书笔记--Android Gradle权威指南(上)

    本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 最近看了一本书<Android Gradle 权威指南>,对于 Gradle 理解又更深了,但不想过段时间就又忘光了,所 ...

  5. Gradle系列之构建脚本基础

    原文发于微信公众号 jzman-blog,欢迎关注交流. 前面两篇文章分别介绍了 Gradle 基础知识以及 Groovy 相关基础知识,这也是学习 Gradle 所必需了解的,文章链接如下:: Gr ...

  6. 《gradle权威指南》--Gradle入门

    No1: Window下搭建Gradle:添加GRADLE_HOME环境变量,然后把GRADLE_HOME\bin添加到PATH系统变量里保存即可.完成后打开CMD,运行gradle -v来验证 No ...

  7. 《Gradle权威指南》--Gradle构建脚本基础

    No1: 设置文件默认名是setting.gradle,放在根目录下,大多数作用都是为了配置子工程 No2: 一个Project包含很多个Task.Task就是一个操作,一个原子性的操作.其实它是Pr ...

  8. 《Gradle权威指南》--Android Gradle多渠道构建

    No1: Build Variant = Build Type + Product Flavor Build Variant:构建的产物 Build Type:构建的类型 Product Flavor ...

  9. 《Gradle权威指南》--Android Gradle多项目构建

    No1: Android多项目设置 目录结构: MyProject/ setting.gradle app/ build.gradle libraries/ lib1/ build.gradle li ...

随机推荐

  1. 知无涯者(The Man Who Knew Infinity)

    1913年的1月16号在剑桥大学的三一学院那里,著名的数学家哈代教授收到了一封信,信的开头是这种: "尊敬的先生.仅自我介绍例如以下,我是马德拉斯港务信托处的一个职员,年薪唯独20英镑.23 ...

  2. amazeui学习笔记--css(常用组件14)--缩略图Thumbnail

    amazeui学习笔记--css(常用组件14)--缩略图Thumbnail 一.总结 1.基本样式:在 <img> 添加 .am-thumbnail 类:也可以在 <img> ...

  3. 洛谷——P1022 计算器的改良

    https://www.luogu.org/problem/show?pid=1022#sub 题目背景 NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在 ...

  4. (转)c++ 中的using namespace std是什么意思,什么时候用

    使用std命名空间 98年以后的c++语言提供一个全局的命名空间namespace,可以避免导致全局命名冲突问题.举一个实例,请注意以下两个头文件: // one.hchar func(char);c ...

  5. 【Codeforces Round #440 (Div. 2) B】Maximum of Maximums of Minimums

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] k=1的时候就是最小值, k=2的时候,暴力枚举分割点. k=3的时候,最大值肯定能被"独立出来",则直接输出最 ...

  6. POJ 2785 4 Values whose Sum is 0 Hash!

    http://poj.org/problem?id=2785 题目大意: 给你四个数组a,b,c,d求满足a+b+c+d=0的个数 其中a,b,c,d可能高达2^28 思路: 嗯,没错,和上次的 HD ...

  7. ERROR:column &quot;rolcatupdate&quot; does not exist

    1.错误描写叙述 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/ ...

  8. Intellij IDEA中使用Debug

    Intellij IDEA中使用Debug Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用 ...

  9. Android自定义组件系列【8】——遮罩文字动画

    遮罩文字的动画我们在Flash中非常常见,作为Android的应用开发者你是否也想将这种动画做到你的应用中去呢?这一篇文章我们来看看如何自定义一个ImageView来实现让一张文字图片实现文字的遮罩闪 ...

  10. angular风格指南

    原文 https://www.jianshu.com/p/1a0a0a74769a 大纲 综述 1.单一职责 2.命名 3.LIFT-D应用程序结构 4.组件 综述 以下说的准则是根据angular官 ...