本文大部份内容来自 Gradle 官方文档,英文 OK 的同窗能够直接看官方文档。 Gradle 系列文章的示例代码都放在了 zjxstar 的 GitHub 上了。html
本文假设你们都已经掌握了 Gradle 构建项目的目录结构。其中,脚本文件 settings.gradle 和 build.gradle 相当重要。Gradle 中的一系列构建操做都基于这两个文件。java
本系列文章想和你们一块儿学习 Gradle 的基础知识,如:Project、Task 和 Transform 等。本文的主要内容是 Project ,其中会涉及到一些简单的 Task,这里不会详细介绍 Task,你们只需知道有 Task 这个概念便可。文中的示例代码都基于 Android Studio 建立的标准 Android 项目。android
在 Gradle 中,最重要的两个概念是 Project(项目) 和 Task(任务)。每一次构建都至少包含一个 Project,每个 Project 又包含了一个或多个 Task。每一个 build.gradle 文件都表明一个 Project,其实 Project 能够理解为在业务范围内,被抽象出来的一个个独立的模块。而 Task 通常被定义在 build.gradle 中,它表示一个操做,好比:复制文件、打个 jar 包、上传文件等。git
以 Android 项目举例说明:github
注:Demo 中使用的 Gradle 版本为 3.3.1 。闭包
使用 Android Studio 建立项目后,会自动生成两个模块,一个是以项目名命名的根模块,另外一个是 app 模块。两个模块中都有 build.gradle 文件,按照前文的说法,就是两个 Project。其中,项目 GradleSample 被称为 rootProject ,项目 app 被称为 subProject 。在根 build.gradle 文件中默认有一个名为 clean 的 Task,它的职责是删除根模块下 build 目录。app
在初始化构建过程当中,Gradle 会基于 build 脚本文件来组装 Project 和 Task。ide
执行一个 Gradle 构建的最简单形式是执行一个 Task,而一些 Task 可能会依赖于其余 Task。Gradle 为了管理这些 Task 会在任何一个 Task 执行前构建一个 DAG 图(Directed Acyclic Graph,有向无环图)。这意味着全部的 Task 都会被一个接一个地执行,并且只执行一次。那些没有依赖的 Task 一般会被优先执行。学习
Gradle 的构建生命周期分为三个阶段:gradle
在 Gradle 构建的初始化阶段,Gradle 会给每一个项目建立一个 Project 对象。那么 Project 又具备怎样的生命周期呢?
Gradle 针对 Project 实例执行项目的构建文件以配置项目。build 脚本中的任何属性和方法都会委托给关联的 Project 对象。这意味着,能够直接在脚本中使用 Project 接口上的任何属性和方法。
例如:
defaultTasks('some-task') // Delegates to Project.defaultTasks()
reportsDir = file('reports') // Delegates to Project.file() and the Java Plugin
复制代码
你也能够经过 Project 实例使用 Project 属性,好比:
project.name // 获取project的名字,而不是单独使用name属性
复制代码
你能够在构建脚本中按照名称访问这些属性,也能够经过 Project 的
project.property(java.lang.String) // 例如:project.property('version')
复制代码
方法来进行访问。
一个项目在搜索属性时会考虑 5 个属性范围:
project.getRootProject()
方法就对应了 rootProject
属性。至于这些属性的可读写性取决于它们是否认义 getters 或者 setters 方法了。名称 -> 值
对。定义后,此做用域的属性是可读写的。好比:project.ext.prop1 = 'foo' 。读写属性时,Project 都是按照上述范围的顺序进行查找的,在某个范围找到属性后就会返回该属性。若是没有找到,会抛出异常。
经常使用的 Project 属性有:
属性名 | 做用 |
---|---|
allprojects | 当前项目及其全部子项目的集合 |
buildDir | 当前项目的编译目录(自动生成) 默认值 porjectDir/build |
defaultTasks | 当前项目的默认任务的名字集 当前构建没有提供任务名时会执行这些默认任务 |
group | 当前项目的组名 |
logger | 当前项目的日志器,能够用来在 build 文件中写日志 |
name | 当前项目的名字 |
parent | 当前项目的父项目 |
path | 当前项目的路径(绝对路径) |
project | 当前项目的实例 |
rootProject | 当前项目层次结构中的根项目 |
subprojects | 当前项目的子项目集 |
tasks | 当前项目的任务集 |
version | 当前项目的版本号,默认值:unspecified |
示例:使用 gradlew build 命令便可运行(基于第一小节图中的 Android 项目)。
// 访问Project的属性
// 在app模块的build.gradle中
println project.group // 打印组名:GradleSample
println version // 打印版本号,默认 unspecified
println project.name // 打印项目名:app
println rootProject.name // 打印根项目的名字:GradleSample
logger.quiet('Test project logger property') // 使用logger
for(String taskName : rootProject.defaultTasks) { // 获取默认任务
println "defaultTask: $taskName" // 打印:defaultTask: clean
}
println rootProject.ext.hello // 打印额外参数
// 在根build.gradle脚本中
defaultTasks 'clean' // 设置默认Task
ext { // 设置额外参数
hello = 'Welcome to Gradle'
}
复制代码
一个项目在搜索方法时,也会考虑 5 个范围:
Task.configure( groovy.lang.Closure )
方法。经常使用的 Project 方法有:
方法名(不列出参数,部分方法有重载) | 做用 |
---|---|
afterEvaluate | 能够添加一个闭包,它会在项目完成评估后当即执行。 当执行属于该项目的构建文件时,会通知此类监听器。 |
allprojects | 配置当前项目以及它的每一个子项目 |
apply | 应用插件或脚本 |
beforeEvaluate | 添加一个闭包,她会在项目开始评估前当即执行 |
configure | 经过闭包配置对象集合 |
copy | 拷贝特定文件 |
file | 解析文件 |
findProperty | 找特定属性,返回它的值,若是没有,返回null |
hasProperty | 判断当前项目有没有指定属性 |
project | 获取指定项目的 project 对象 |
setProperty | 给属性设置值 |
subprojects | 配置当前项目的全部子项目 |
task | 定义一个任务 |
示例:使用 gradlew -q helloTask 命令运行便可。
// 根build.gradle
allprojects {
// 给全部项目都添加一个任务:helloTask
task helloTask {
doLast { task ->
println "I'm ${task.project.name}"
}
}
}
subprojects {
helloTask { // 给全部子项目中的helloTask任务增长一个doFirst回调
doFirst {
println "I'm the task in sub project, doFirst"
}
}
afterEvaluate { project ->
println "it's after evaluate..."
helloTask.configure {
doLast {
println "configure task after evaluate"
}
}
}
}
// 给全部的子项目(除了app项目)的helloTask配置doLast
configure(subprojects.findAll{ it.name != 'app' }) {
helloTask {
doLast {
println "i am not app module, i configure doLast"
}
}
}
复制代码
输出结果:
it's after evaluate...
I'm GradleSample
I'm the task in sub project, doFirst
I'm app
configure task after evaluate
复制代码
本文的内容很少,详细介绍了 Gradle 中 Project 的生命周期、属性和方法。同时,概述了 Gradle 构建项目的三个时期,并提到了 Task 。其实,Gradle 主要仍是围绕 Task 来运转的,后续文章咱们将学习 Task 的一系列知识。