00. Gradle 入门

Gradle 是一款非常优秀的构建系统工具,可在所有主流操作系统上运行,并且只需要Java开发工具包版本 8 或更高版本即可运行。 要进行检查,请运行 java -version

配置 Gradle 环境

Linux 下搭建 Gradle 构建环境

先到 Gradle 官网 https://gradle.org/ 下载 Gradle。这里区分 binary-only 版或者 complete 版(with docs and sources)

将发行版 zip 文件解压缩到你选择的目录中,例如:

1
2
mkdir /opt/gradle
unzip -d /opt/gradle gradle-7.6-bin.zip

配置你的 PATH 环境变量

1
export PATH=$PATH:/opt/gradle/gradle-7.6/bin

在 Linux 下,如果你只想为你当前登录的用户配置可以运行 Gradle,那么可以编辑 ~/.bashrc 文件添加以下内容,然后在终端输入 source ~/.bashrc 让刚刚的配置生效。如果你想让所有用户都可以使用 gradle,那么你就需要在 /etc/profile 中添加以上内容,在这里添加后,对所有用户都生效,这种方式的添加,必须要重启电脑才可以。

输入 gradle -v 命令查看即可,如果能正确显示 gradle 版本号、Groovy 版本号、JVM 等相关信息,那么说明你已经配置成功了。

Mac 下搭建 Gradle 构建环境

与 Linux 类似。在终端中输入:open -e ~/.bash_profile,打开.bash_profile文件

Reload your terminal to see this change reflected or run the following command:
$ source ~/.bash_profile

Window 下搭建 Gradle 构建环境

环境变量配置项,添加 GRADLE_HOME 环境变量,然后把 GRADLE_HOME\bin 添加到 PATH 系统变量里保存即可。完成后打开 CMD 运行 gradle -v 来进行验证,整体和 Linux 差不多。

关于配置环境变量的说明

配置 GRADLE_USER_HOME Gradle 用户主目录【可选配置】
用于存储全局配置属性和初始化脚本以及缓存和日志文件。
如果不配置该属性,则默认的目录为 $USER_HOME/.gradle,在 windows 系统中默认为 C:\Users\当前电脑用户名/.gradle。之后方便定制化 init.gradle(.kts) 脚本。这个 init.gradle 像极了 maven 中的 settings.xml 文件。

因此如果 windows 系统 C 盘不够用,可以指定到非系统盘的某个目录中。

配置 GRADLE_HOME【我一般缺省不配】
你也可以添加环境变量 GRADLE_HOME 并将其指向解压缩的发行版。 您可以将 $GRADLE_HOME/bin 添加到 PATH 中,而不是将特定版本的 Gradle 添加到 PATH 中。升级到其他版本的 Gradle 时,只需更改 GRADLE_HOME 环境变量即可。

在我我的实践中,一般自己用 gradle wrapper 用的比较多,因此我一般缺省不配。

Gradle 版 Hello World

新建好一个目录,然后在该目录下创建一个名为 build.gradle 的文件,打开编辑该文件,输入以下内容:

1
2
3
4
5
task hello {
doLast {
println'Hello world!'
}
}

cd 到对应目录来执行构建脚本:gradle -q hello。这条命令的意思是要执行 build.gradle 脚本中定义的名为 hello 的 Task,-q 参数用于控制 gradle 输出的日志级别,哪些日志可以输出被看到。

看到 println ‘Hello World!’ 了吗,它会输出 Hello World!,通过名字相信大家已经猜出来了,它其实就是 System.out.println(“Hello World!”) 的简写方式。Gradle 可以识别它,是因为 Groovy 已经把 println() 这个方法添加到 java.lang.Object,而在 Groovy 中,方法的调用可以省略签名中的括号,以一个空格分开即可,所以就有了上面的写法。还有一点要说明的就是在 Groovy 中,单引号和双引号所包含的内容都是字符串,不像 Java 中,单引号是字符,双引号才是字符串。

Gradle 命令行

构建 Setup tasks

init 任务

init - Initializes a new Gradle build.

1
gradle init

Gradle 提供了通过 Groovy 或基于 kotlin 的 DSL 创建和配置任务的 api。 Project 包括一组 Tasks,每个 Tasks 执行一些基本操作。

build.gradle 用于配置当前项目的 gradle 生成脚本
gradlew 和 gradlew.bat 分别是 Linux 和 Window 下的可执行脚本,他们的用法和 gradle 原生命令是一样的,gradle 怎么用,他们也就可以怎么用。
gradle-wrapper.jar 是具体业务逻辑实现的 jar 包,gradlew 最终还是使用 java 执行的这个 jar 包来执行相关 gradle 操作。gradle-wrapper.properties 是配置文件,用于配置使用哪个版本的 gradle 等。
settings.gradle 配置 gradle 构建的设置脚本

这些生成的 wrapper 文件可以作为你项目工程的一部分提交到代码版本控制系统里(git),这样其他开发人员就会使用这里配置好的统一的 gradle 进行构建开发。

wrapper 任务

wrapper - Generates Gradle wrapper files.

Wrapper,顾名思义,其实就是对 Gradle 的一层包装,便于在团队开发过程中统一 Gradle 构建的版本,这样大家都可以使用统一的 Gradle 版本进行构建,避免因为 Gradle 版本不统一带来的不必要的问题。

Gradle 提供了内置的 wrapper task 帮助我们自动生成 wrapper 所需的目录文件,在一个已是 gradle 项目的根目录,输入 gradle wrapper 即可生成。

1
2
3
4
5
6
7
8
--
│ gradlew
│ gradlew.bat

└─gradle
└─wrapper
gradle-wrapper.jar
gradle-wrapper.properties

自定义 Wrapper Task
前面我们讲了,gradle-wrapper.properties 是由 wrapper task 生成的,那么我们是否可以自定义配置该 Wrapper task 来达到我们配置 gradle-wrapper.properties 的目的呢,答案是肯定的。我们可以在 build.gradle 按需添加配置到 build.gralde 构建文件中:

1
2
3
wrapper  {
gradleVersion = '7.6'
}

这样我们再执行 gradle wrapper 的时候,就更改了将生成 7.6 版本的 wrapper。当然通过命令行也能达到同样的效果,gradle wrapper --gradle-version 7.9

gradle help

首先可以gradle help 了解一下常用的命令。前提是该目录已经是一个 gradle 项目,否则需要事先进行初始化。
除了上面我们说的每个命令行都有帮助外,Gradle 还内置了一个 help --task,可以让我们了解每一个 task 的使用帮助,
用法是 gradle help --task <task name>
比如 gradle help --task tasks,显示 tasks 任务的帮助信息。
gradle help --task initgradle help --task wrapper

记得使用帮助

命令行下的工具都有命令,刚开始我们不会用或者不知道有什么命令或者参数,这没事,但是我们可以通过帮助来了解,基本上所有的命令行工具都有帮助,查看帮助的方式也很简单,基本上都是在命令后跟 -h 或者 --help,有的时候会有 -?,以 Gradle Wrapper 为例:

gralde -?
gralde -h
gralde --help

查看所有可执行的 Tasks

Tasks 命令列出了可以调用的 Gradle 任务,包括由基础插件添加的任务,以及刚刚添加的自定义任务。

要查看所有任务和更多细节,请运行 gradle tasks --all

多任务调用

有时候我们需要同事运行多个任务,比如在执行 Jar 之前先进行 clean,那么我们就需要先执行 clean 对 class 文件清理,然后再执行 jar 生成一个 jar 包。通过命令行执行多个任务非常简单,只需要按顺序以空格分开即可,比如 gradle clean jar,这样就可以了,有更多的任务时,可以继续添加。

通过任务名字缩写执行执行

有的时候我们的任务名字很长,Gradle 提供了基于驼峰命名法的缩写调用,比如 connectCheck,我们执行的时候可以使用 gradlew connectCheck, 也可以使用 gradlew cc 这样的方式来执行。

强制刷新依赖

我们一个功能不可避免的会依赖很多第三方库,像 Maven 这类工具都是有缓存的,因为不可能每次编译的时候都要重新下载第三方库,缓存就是这个目的,先使用缓存,没有再下载。默认情况下 Maven 这类工具会控制缓存的更新,但是也有例外,比如 Version 一样,但是里面的代码变了;还有就是联调测试时使用的 snapshot 版本。以上两种情况我们在实际项目中都遇到过,最后就是通过强制刷新解决的。

强制刷新很简单,只要在命令行运行的时候加上 --refresh-dependencies 参数就可以,这是 IDE 很难做到的(需要你了解配置),所以命令行的优势就体现出来了。

gradle --refresh-dependencies assemble

Gradle 日志

日志级别

级别 用途
ERROR 错误信息
QUIET 重要信息
WARNING 警告信息
LIFECYCLE 进度信息
INFO 内容信息
DEBUG 调试信息
1
2
3
4
5
6
7
8
# 输出 quiet 级别及其以上的日志
gradle -q tasks
# 输出 warn 级别及其以上的日志
gradle -w tasks
# 输出 info 级别及其以上的日志
gradle -i tasks
# 输出 debug 级别及其以上的日志
gradle -d tasks

输出错误堆栈信息

在使用 Gradle 构建的时候,难免会有这样或者那样的问题导致你的构建失败,这时就需要你根据日志分析解决问题。除了以上的日志信息之外,Gradle 还提供了堆栈信息的打印,用过 Java 语言的相信大家都会很熟悉错误堆栈信息,他能帮助我们很好的定位和分析问题。

默认情况下,堆栈信息的输出是关闭的,需要我们通过命令行的堆栈信息开关打开它,这样在我们构建失败的时候,Gradle 才会输出错误堆栈信息,便于我们定位分析和解决问题。

命令行选项 用途
无选项 不输出堆栈信息
-s 或 --stacktrace 输出关键性的堆栈信息
-S 或 --full-stacktrace 输出全部堆栈信息

在编写 Gradle 脚本的过程中,我们有时候需要输出一些日志,来验证我们的逻辑或者一些变量的值是否正确,这时候我们就可以使用Gradle 提供的日志功能。
通常情况下我们一般都是使用 print 系列方法,把日志信息输出到标准的控制台输出流(它被 Gradle 定向为QUIET级别日志)。

除了 print 系列方法之外,你也可以使用内置的 logger 更灵活的控制输出不同级别的日志信息。

1
2
3
4
5
6
logger.quiet('quiet 日志')
logger.error('error 日志')
logger.warn('warn 日志')
logger.lifecycle('lifecycle 日志')
logger.info('info 日志')
logger.debug('debug 日志')

logger 虽说是内置,其实是调用的 Project 的 getLogger() 方法获取的 Logger 对象的实例。

分析和调试您的构建 Analyze and debug your build

Gradle 提供了一个简单的 Java 项目,您可以使用它来演示构建扫描功能。 如果你想使用它,克隆或下载存储库。

1
2
3
$ git clone https://github.com/gradle/gradle-build-scan-quickstart
Cloning into 'gradle-build-scan-quickstart'...
$ cd gradle-build-scan-quickstart

从 Gradle 4.3 开始,您可以启用构建扫描,而无需在构建脚本中进行任何附加配置。 当使用命令行选项 ——scan 发布构建扫描时,所需的构建扫描插件将自动应用。 在构建结束之前,您被要求在命令行上接受许可协议。 下面的控制台输出演示了该行为。

1
gradle build --scan

如果你浏览你的构建扫描,你应该能够很容易地找出什么任务被执行,他们花了多长时间,哪些插件被应用,等等。 下次在 StackOverflow 上调试某些内容时,可以考虑共享构建扫描。

配置 Gradle 核心任务

copy 任务

Gradle 提供了一个任务库,您可以在自己的项目中进行配置。 例如,有一种名为 Copy 的核心类型,它将文件从一个位置复制到另一个位置。 Copy 任务非常有用(有关详细信息,请参阅文档) ,但是在这里,让我们再次保持它的简单性。 执行以下步骤:

  1. 创建一个名为 src 的目录。
  2. 在 src 目录中添加名为 myfile.txt 的文件。 内容是任意的(甚至可以为空) ,但为了方便起见,添加单行 Hello,World! 对它。
  3. 在 build.gradle 文件中,在构建文件中定义一个名为 type: Copy (注意大写字母)的任务,该任务将 src 目录复制到名为 dest 的新目录。 (您不必创建 dest 目录ー任务会为您完成。)
1
2
mkdir src
echo HelloWorld > src/myfile.txt
1
2
3
4
task copy(type: Copy, group: "Custom", description: "Copies sources to the dest directory") {
from "src"
into "dest"
}

在这里,groupdescription 可以是任何你想要的。 您甚至可以省略它们,但这样做也会在任务报告中省略它们,以后再使用。

现在执行新的复制任务:

1
gradle copy

其他命令

zip 命令

包括了一系列插件,更多的插件可以在 Gradle 插件门户网站上找到。 发行版中包含的插件之一是 basic 插件。 结合名为 Zip 的核心类型,可以使用已配置的名称和位置创建项目的 Zip 归档。

1
2
3
4
5
6
plugins {id "base"}

task zip(type: Zip, group: "Archive", description: "Archives sources in a zip file") {
from "src"
setArchiveFileName "basic-demo-1.0.zip"
}

基础插件使用设置在 build / distribution 文件夹中创建一个名为 basic-demo-1.0.zip 的归档文件。

1
gradle zip

Discover available properties 发现可用属性

1
gradle properties

其中 buildFile 属性是构建脚本的完全限定路径名,默认情况下位于 projectDir 中。

您可以更改许多属性。 例如,您可以尝试将以下行添加到 build.gradle 文件中,并重新执行 gradle 属性。

1
2
description = "A trivial Gradle build"
version = "1.0"

参考

本文纯属自学历程 + 一些记录,部分内容来自原书 Android Gradle 权威指南。觉得对你有用,请支持原书。

Gradle教程 | 程序员笔记
https://www.knowledgedict.com/tutorial/gradle-intro.html

Gradle User Guide 中文版
http://blog.didispace.com/books/GradleUserGuide/