Gradle
Gradle 基础
Gradle 是一个框架,它定义了一套自己的游戏规则。我们要玩转 Gradle,必须要遵守它设计的规则。
Gradle 介绍
Gradle 是什么?
Gradle 是一个自动化构建工具。Gradle 是通过组织一系列 task 来最终完成自动化构建的,所以 task 是 Gradle 里最重要的概念
我们以生成一个可用的 apk 为例,整个过程要经过资源的处理,javac 编译,dex 打包,apk 打包,签名等等步骤,每个步骤就对应到 Gradle 里的一个 task。
环境安装
Gradle 是一个 运行在 JVM 的通用构建工具。Gradle 基于 JVM, 因此需要 Java 环境 (1.8 及以上版本)。
其核心模型是一个 Task 组成的有向无环图 (Directed Acyclic Graphs).
两个重要的环境变量:
GRADLE_HOME
这个环境变量的作用是告诉操作系统 Gradle 的安装目录。GRADLE_USER_HOME
类似于用户的 home 目录 ($HOME), 用于存放 Gradle 运行时的一些通用配置, 缓存等等。默认值是 $HOME/.gradle
, 一般不用单独配置。
Gradle Wrapper
Wrapper 是对 Gradle 的一层包装,方便在团队中统一管理 Gradle 的版本,项目开发中通常使用的 Wrapper 这种方式,使用 Wrapper 之后就不需要采用配置 Gradle 的构建环境的方式,使用 Wrapper 启用 Gradle 的时候,Wrapper 会检查 Gradle 有没有下载关联,如果没有下载则从配置的地址下载并进行构建,这就一定程度上方便开发人员构建项目。
- gradle wrapper 生成的文件目录如下:
1
2
3
4
5
6
| │─gradlew
│─gradlew.bat
└─gradle
└─wrapper
gradle-wrapper.jar
gradle-wrapper.properties
|
- gradle-wrapper.properties
1
2
3
4
5
| distributionBase=xxx #下载的Gradle压缩包解压后存储的主目录
distributionPath=xxx #相对于distributionBase解压后压缩包的路径
zipStoreBase=xxx #相对于distributionBase存放Gradle压缩包的
zipStorePath=xxx #相对于distributionPath存放Gradle压缩包的
distributionUrl=xxx #Gradle的下载地址,一般是官网地址
|
1
2
3
4
5
6
7
| task wrapper(type: Wrapper){
gradleVersion = '3.3'
distributionBase='GRADLE_USER_HOME'
distributionPath='wrapper/dists'
//注意不要这样写:https\://services...
distributionUrl="https://services.gradle.org/distributions/gradle-3.3-all.zip"
}
|
- Wrapper 源码路径:
$HOME/.gradle/wrapper/dists/gradle-6.5-all/src/wrapper/
Gradle 日志
Gradle 日志主要跟踪构建过程以及调试错误。
Gradle 日志级别
Gradle 的日志级别主要有六种,具体如下:
1
2
3
4
5
6
| ERROR // 错误消息
QUIET // 重要消息
WARNING // 警告消息
LIFECYCLE // 进度消息,默认日志输出最低级别
INFO // 信息消息
DEBUG // 调试信息
|
使用时可以通过命令行的方式控制日志显示级别,下面是可以使用命令控制的日志选项,具体如下:
1
2
3
| -q 或 --quiet // 表示QUIET及其更高级别
-i 或 --info // 表示INFO及其更高级别
-d 或 --debug // DEBUG 及其更高级别(输出所有日志)
|
如果不指定,则默认输出的日志是 LIFECYCLE 及其更高级别的日志。
- print 系列方法将日志输出到控制台,这属于 QUIET 级别的日志
- 使用内置的 logger 来控制不同级别日志的显示,及 DEBUG 输出日志最完整、ERROR 输出日志最少
1
2
3
4
5
6
7
8
9
10
11
12
13
| //日志测试
task hello {
doLast{
println '======>>>>>> Hello world'
print '======>>>>>> Hi'
logger.error('======>>>>>> error 日志')
logger.quiet('======>>>>>> quiet 日志')
logger.warn('======>>>>>> warn 日志')
logger.lifecycle('======>>>>>> lifecycle 日志')
logger.info('======>>>>>> info 日志')
logger.debug('======>>>>>> debug 日志')
}
}
|
命令:
输出 (info 和 debug 级别的日志没有输出):
1
2
3
4
5
6
| ======>>>>>> Hello world
======>>>>>> error 日志
======>>>>>> quiet 日志
======>>>>>> warn 日志
======>>>>>> lifecycle 日志
======>>>>>> Hi
|
./gradlew hello --debug
将输出所有日志
输出堆栈信息
默认情况下,堆栈信息的输出是关闭的,可以通过命令行的堆栈信息开关打开它,当构建失败后,Gradle 会将输出错误的堆栈信息,方便定位和分析问题。打开方式具体如下:
1
2
| -s 或 --stacktrace // 输出关键性的堆栈信息
-S 或 --full--stacktrace // 输出全部堆栈信息
|
一般使用 -s 就可以了。
Command-Line Interface Reference
Command-Line Interface Reference
常用 Gradle 命令
gradle projects
- gradle projects 查看有多少个工程信息
查看这个 multi projects 到底包含多少个子 Project:
gradle tasks
- gradle tasks 查看可执行的 Tasks,执行结果以分组形式输出,一个是关于构建的 (Build Setup tasks),另一个是关于帮助的 (Help 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
| PS E:\Gradle\study\wrapper> ./gradlew tasks
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Help tasks
----------
components - Displays the components produced by root project 'wrapper'. [incubating]
dependencies - Displays all dependencies declared in root project 'wrapper'.
dependencyInsight - Displays the insight into a specific dependency in root project 'wrapper'.
help - Displays a help message.
model - Displays the configuration model of root project 'wrapper'. [incubating]
projects - Displays the sub-projects of root project 'wrapper'.
properties - Displays the properties of root project 'wrapper'.
tasks - Displays the tasks runnable from root project 'wrapper'.
To see all tasks and more detail, run gradlew tasks --all
To see more detail about a task, run gradlew help --task <task>
BUILD SUCCESSFUL
Total time: 8.4 secs
|
1
2
3
4
| // 命令格式
gradle help --task Task名称
// 举例
gradle help --task projects
|
查看依赖
[[03.Gradle依赖#dependencies查看]]
其他命令
gradle clean
执行清理任务gradle properties
查看所有属性信息gradle 指定moudle执行编译任务
./gradlew :<ModuleName>:assembleRelease
如:
1
| ./gradlew --debug :libcommon:build
|
1
| ./gradlew taskXXX --refresh-dependencies
|
构建选项
--profile
--profile
选项输出构建时会执行的任务列表,以及每一个任务耗时情况:
1
| ./gradlew :app:assembleDebug --profile
|
-q
-q 选项表示静默构建,只会打印出 error 信息:
1
| ./gradlew :app:assembleDebug -q
|
--offline
–offline 选项表示构建时不访问网络资源:
1
2
| ./gradlew :app:assembleDebug --offline -q
|
--info
–info 选项表示构建时,打印出 info 信息:info 信息包含构建时,所有 task 相关的信息,这有助于排查构建问题,或帮助熟悉项目构建情况。
1
| ./gradlew :app:assembleDebug --info
|
--s
–s 选项表示构建时,打印出异常的所有栈信息:
1
| ./gradlew :app:assembleDebug --s
|
--refresh-dependencies
–refresh-dependencies 选项表示构建时,刷新相关依赖:
1
2
| ./gradlew :app:assembleDebug --refresh-dependencies
# 如果更新了项目相关依赖库版本,在构建后发现没有生效,就可以使用这个选项。
|
--no-build-cache
–no-build-cache 选项表示构建时,不使用构建缓存:
1
| ./gradlew :app:assembleDebug --no-build-cache
|
如果更改了项目代码,在构建后发现没有生效,就可以使用这个选项,或者执行 clean。
备注:这个选项在 Gitlab CI 中构建,或远程构建项目时,发现更改代码没有生效,可以选择使用。
Gradle 自带变量和引用属性值
Project 可用的标准属性
1
2
3
4
5
6
7
8
9
| // Project可用的标准属性
println "name-->" + name // app --项目目录
println "project-->" + project // project ':app' -- project实例
println "project.name-->" + project.name // app
println "project.path-->" + project.path // :app --项目绝对路径
println "project.description-->" + project.description // null --项目描述
println "project.projectDir-->" + project.projectDir // D:\workspace_studio\GradleDemo\app --包含生成脚本的目录
println "project.buildDir-->" + project.buildDir // D:\workspace_studio\GradleDemo\app\build --build目录
println "project.ant-->" + project.ant // org.gradle.api.internal.project.DefaultAntBuilder@139d5492 --AntBuilder实例
|
Android for gradle 自带变量
1
2
3
4
5
6
7
8
9
10
11
12
| println '[rootDir]' + rootDir // D:\workspace_studio\GradleDemo
println '[buildDir]' + buildDir
println '[projectDir]' + projectDir
println '[project]' + project
println '[project]' + project.getName();
println '[rootProject]' + rootProject
// [rootDir]D:\workspace_studio\GradleDemo
// [buildDir]D:\workspace_studio\GradleDemo\app\build
// [projectDir]D:\workspace_studio\GradleDemo\app
// [project]project ':app'
// [project]app
// [rootProject]root project 'GradleDemo'</pre>
|
引用配置文件 gradle.properties
里的变量
注意:
- 要注意参数类型要与
gradle.properties
对应,如果是配置的是 true,不是 boolean 是个 string,获取的时候判断 xxx.toBoolean()
- 配置的都是 string,所有 value 不用有 ““,不然获取出来的带
""
gradle.properties
1
2
3
4
5
6
| sdk.dir=D\:\\adt-bundle-windows-x86_64-20140702\\sdk
sdk.ndk = D\:\\ndk
isRunWithAAR=true
libwidget=true
libcommon=true
|
引用方式
- 直接获取属性名
1
| println 'myLibrary1'+novoda_bintray
|
- project.properties.get(“ 属性名 “) 获取
1
| println 'myLibrary1'+project.properties.get("novoda_bintray")
|
settings.gradle 引用 gradle.properties(直接引用或 project.properties.get)
1
2
3
4
5
6
7
8
9
10
11
12
| println('================ settings.gradle配置 ================\n')
println('isRunWithAAR=' + (isRunWithAAR.toBoolean()) + ", libcommon=" + libcommon.toBoolean() + ", libwidget=" + libwidget.toBoolean())
println('================ settings.gradle配置 end ================\n')
if (!isRunWithAAR.toBoolean() || !libcommon.toBoolean()) {
println('------include :libcommon------\n')
include ':libcommon'
}
if (!isRunWithAAR.toBoolean() || !libwidget.toBoolean()) {
println('------include :libwidget------\n')
include ':libwidget'
}
|
根目录的 build.gradle 引用 (直接引用或 project.properties.get)
1
2
3
4
| println novoda_bintray
if (novoda_bintray.toBoolean()){
println("开启了novoda_bintray")
}
|
app 的 build.gradle 引用 (直接引用或 project.properties.get)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| buildTypes {
release {
......
buildConfigField("String", "appKey", project.properties.get("appKey"))
buildConfigField("String", "appType", project.properties.get("appType"))
buildConfigField "String", "hotfixTag", hotfixTag
buildConfigField("boolean", "useAndroidX", project.properties.get("android.useAndroidX"))
}
debug {
......
buildConfigField("String", "appKey", project.properties.get("appKey"))
buildConfigField("String", "appType", project.properties.get("appType"))
buildConfigField "String", "alihotfixFlag", alihotfixFlag
buildConfigField("boolean", "useAndroidX", project.properties.get("android.useAndroidX"))
}
}
|
其他脚本
1
2
3
4
5
| // 使用 project.hasProperty('sdk.dir') 判断key值是否存在
println '[sdk.dir]:' + project.hasProperty("sdk.dir") // true
println '[sdk.ndk]:' + project.hasProperty("sdk.ndk") // true
println '[sdk.hacket]:' + project.hasProperty("sdk.hacket") // false
// 使用project.properties['sdk.dir']进行key值的value引用
|
Project
[[Gradle Project]]