相关文章:
- Gradle核心思想(一)为什么现在要用Gradle?
- Gradle核心思想(二)Gradle入门前奏
- Gradle核心思想(三)Groovy快速入门指南
- Gradle核心思想(四)看似无用,实则重要的Gradle Wrapper
- Gradle核心思想(五)通俗易懂的Gradle插件讲解
- Gradle核心思想(六)自定义Gradle插件的三种方式
- Android Gradle(一)Gradle的Android插件入门
- Android Gradle(二)签名配置和依赖管理
前言 {#前言}
在上一篇文章Gradle核心思想(一)为什么现在要用Gradle?中,我们学习了常见的构建工具,以及Gradle与这些构建工具相比有那些不同的特性。这一篇文章我们接着来学习Gradle入门需要掌握的知识,包括配置环境、实现Hello World、Gradle的任务、Gradle日志和Gradle命令行,掌握这些能够更好的理解Gradle。
配置Gradle环境 {#配置Gradle环境}
安装Gradle前要确保系统已经配置好JDK的环境,要求JDK的版本在1.7或更高。
Gradle的安装有两种形式:
- 通过包管理安装,比如Window平台的Chocolatey、Scoop,Mac平台的MacPortsl、Homebrew等等。
- 手动安装。
关于包管理器安装可以查看官方文档 ,这里主要介绍手动安装,在 https://gradle.org/releases/
中下载你想要Gradle版本的binary-only。
Windows平台安装 {#Windows平台安装}
和配置Java环境类似,在系统变量中添加GRADLE_HOME:
然后再将%GRADLE_HOME%\bin添加到path系统变量中就可以了,运行gradle -v命令来进行验证。
Mac平台安装 {#Mac平台安装}
步骤如下:
-
打开终端运行open -e .bash_profile,打开.bash_profile文件来配置环境变量。
-
在.bash_profile文件中将gradle路径添加到path环境变量中,比如我的就是:
|-----------|-------------------------------------------------------| |
1
|export PATH=$PATH:~/develop/gradle-4.10.1/bin
| -
保存.bash_profile文件,在终端中运行source ~/.bash_profile,更新.bash_profile文件。
-
在终端上运行gradle -v命令,查看是否配置成功。
实现Hello World {#实现Hello-World}
配置完Gradle环境后,按照惯例要实现Gradle的Hello World,这里以Windows平台为例。
build.gradle为Gradle默认的构建脚本文件,运行Gradle 命令时,会从当前目录下寻找 build.gradle 文件来执行构建。
我们先新建一个目录,比如D:\Android\gradle_demo,在这个目录中新建一个 build.gradle 文件,输入以下内容:
|-------------------|----------------------------------------------------------|
| 1 2 3 4 5
| task hello { doLast { println 'Hello world!' } }
|
然后在该文件所在目录下运行gradle -q hello
构建脚本, 就会打印出"Hello world!"。
项目构建比较复杂,为了使用各种开发语言的开发者都能够快速的构建项目,专家们开发出了Gradle这个基于Groovy的DSL,DSL(Domain Specifc Language)意为领域特定语言,只用于某个特定的领域。我们只要按照Groovy的DSL语法来写,就可以轻松构建项目。
task(任务)和action(动作)是Gradle的重要元素。上面的代码中,task代表一个独立的原子性操作,比如复制一个文件,编译一次Java代码,这里我们简单的定义一个名为hello的任务。doLast 代表task执行的最后一个action,通俗来讲就是task执行完毕后会回调doLast中的代码,在上面这个例子中就会打印 'Hello world!'
上面的例子还可以写的更简洁一些,操作符<< 是doLast方法的快捷版本,它们做了相同的事情,如下所示。
|---------------|--------------------------------------------------|
| 1 2 3
| task hello << { println 'Hello world!' }
|
Gradle的任务 {#Gradle的任务}
为了更好的讲解后面的Gradle 命令行,这里简单的介绍下Gradle的任务,包括创建任务、任务依赖、 动态定义任务和任务的分组和描述。
创建任务 {#创建任务}
除了第2节实现Hello World的例子采用的创建任务方式,还有其他的3种创建任务方式。
- 直接用任务名称创建。
|-----------------|--------------------------------------------------------------------------|
| 1 2 3 4
| def Task hello=task(hello) hello.doLast{ println "hello world" }
|
- 任务名称+任务配置创建。
|-----------------|-------------------------------------------------------------------------------------------------------|
| 1 2 3 4
| def Task hello=task(hello,group:BasePlugin.BUILD_GROUP) hello.doLast{ println "hello world" }
|
其中group为任务配置项,它代表了分组,关于分组具体见3.4小节。
- TaskContainer的create方法创建。
|---------------|------------------------------------------------------------------|
| 1 2 3
| tasks.create(name: 'hello') << { println "hello world" }
|
此前创建任务的方式最终都会调用tasks的create方法,其中tasks类型为TaskContainer。
任务依赖 {#任务依赖}
任务依赖会决定任务运行的先后顺序,被依赖的任务会在定义依赖的任务之前执行。创建任务间的依赖关系如下所示。
|---------------------|-------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6
| task hello << { println 'Hello world!' } task go(dependsOn: hello) << { println "go for it" }
|
在hello任务的基础上增加了一个名为go的任务,通过dependsOn来指定依赖的任务为hello,因此go任务运行在hello之后。
运行gradle -q go构建脚本,打印结果如下:
Hello world!
go for it
动态定义任务 {#动态定义任务}
动态定义任务指的是在运行时来定义任务的名称,如下所示。
|-------------------|-------------------------------------------------------------------------------|
| 1 2 3 4 5
| 3.times {number -> task "task$number" << { println "task $number" } }
|
这里用到了Groovy语法,关于Groovy语法会在本系列后续的文章进行介绍。times是Groovy在java.lang.Number中拓展的方法,是一个定时器。3.times中循环创建了三个新任务,隐式变量number的值为0,1,2,任务的名称由task加上number的值组成,达到了动态定义任务的目的。
运行gradle -q task0构建脚本,打印结果如下:
task 0
任务的分组和描述 {#任务的分组和描述}
Gradle有任务组的概念,可以为任务配置分组和描述,以便于更好的管理任务,拥有良好的可读性。改造3.2小节的例子,为hello任务添加分组和描述。
|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11
| task hello { group = 'build' description = 'hello world' doLast { println "任务分组: ${group}" println "任务描述: ${description}" } } task go(dependsOn: hello) << { println "go for it" }
|
也可以采用3.1小节中其他的创建任务方式来为任务添加分组和描述,如下所示。
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10
| def Task hello=task(hello) hello.description ='hello world' hello.group=BasePlugin.BUILD_GROUP hello.doLast{ println "任务分组: ${group}" println "任务描述: ${description}" } task go(dependsOn: hello) << { println "go for it" }
|
4.Gradle日志级别
和Android一样,Gradle也定义了日志级别。
| 级别 | 用于 | |-----------|---------| | ERROR | 错误消息 | | QUIET | 重要的信息消息 | | WARNING | 警告消息 | | LIFECYCLE | 进度信息消息 | | INFO | 信息性消息 | | DEBUG | 调试消息 |
前面我们通过gradle -q +任务名称来运行一个指定的task,这个q是命令行开关选项,通过开关选项可以控制输出的日志级别。
| 开关选项 | 输出日志级别 |
|----------------|----------------|
| 无日志选项 | LIFECYCLE及更高级别 |
| -q或者 --quiet
| QUIET及更高级别 |
| -i或者 --info
| INFO及更高级别 |
| -d或者 --debug
| DEBUG及更高级别 |
Gradle 命令行 {#Gradle-命令行}
从命令行的角度,Gradle和Git类似,命令都可以用一些IDE、图形工具来代替,但是如果你对Gradle 命令行熟悉,会帮助你更好的理解Gradle,高效的运用Gradle。
获取所有任务信息 {#获取所有任务信息}
这一节的命令行以3.4小节的代码为例,此前我们通过gradle -q +任务名称来运行一个指定的任务,如果不知道任务的名称,可以通过运行gradle -q tasks命令来获取所有的任务信息,这样就不需要打开源码了。
|---------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| Build tasks ----------- hello - hello world Build Setup tasks ----------------- init - Initializes a new Gradle build. wrapper - Generates Gradle wrapper files. Help tasks ---------- buildEnvironment - Displays all buildscript dependencies declared in root projec t 'gradle_demo'. components - Displays the components produced by root project 'gradle_demo'. [in cubating] dependencies - Displays all dependencies declared in root project 'gradle_demo'. dependencyInsight - Displays the insight into a specific dependency in root proj ect 'gradle_demo'. dependentComponents - Displays the dependent components of components in root pr oject 'gradle_demo'. [incubating] help - Displays a help message. model - Displays the configuration model of root project 'gradle_demo'. [incubat ing] projects - Displays the sub-projects of root project 'gradle_demo'. properties - Displays the properties of root project 'gradle_demo'. tasks - Displays the tasks runnable from root project 'gradle_demo'. To see all tasks and more detail, run gradle tasks --all To see more detail about a task, run gradle help --task <task>
|
默认情况下,只会显示那些被分组的任务的名称和描述。比如Build tasks(Build 任务组)中有我们定义的hello任务,Build Setup tasks中有init和wrapper,Help tasks有buildEnvironment 和components等等。
排除任务 {#排除任务}
如果我们不想运行go任务,可以运行gradle hello -x go命令:
|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12
| > Task :hello 任务分组: build 任务描述: hello world Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/4.10.1/userguide/command_line_interface.html#sec:com mand_line_warnings BUILD SUCCESSFUL in 2s 1 actionable task: 1 executed
|
可以看出,并没有运行go任务。
获取任务帮助信息 {#获取任务帮助信息}
通过运行gradle -q help --task hello
命令来显示hello任务的帮助信息。
|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13
| Detailed task information for hello Path :hello Type Task (org.gradle.api.Task) Description hello world Group build
|
可以看到hello任务的路径、类型、描述和分组。
多任务调用 {#多任务调用}
|---------------------|----------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6
| task helloWorld << { println 'Hello world!' } task goForit<< { println "go for it" }
|
通过命令行一次执行多个任务,每个任务通常只会执行一次,无论是在命令行中指定任务还是任务依赖,上面的例子我们运行gradle helloWorld goForit,会先执行helloWorld任务后执行goForit任务。
任务名称缩写 {#任务名称缩写}
可以对使用驼峰命名的任务进行缩写,对于名称特别长的任务这个特性非常有用,比如5.4小节中的例子只需要执行gradle hW gF
就可以了,不过需要注意一点,那就是任务名称的缩写必须是唯一的,如果5.4小节中第二个任务的名称为helloWangshu,那么就会报错。
参考链接:http://liuwangshu.cn/application/gradle/2-primer.html