
一、前言

????從明面上看,Gradle 是一款強大的構建工具,但 Gradle 不僅僅是一款強大的構建工具,它更像是一個編程框架。Gradle 的組成可以細分為如下三個方面:
????groovy 核心語法:包括 groovy 基本語法、閉包、數據結構、面向對象等等。
Android DSL(build scrpit block):Android 插件在 Gradle 所特有的東西,我們可以在不同的 build scrpit block 中去做不同的事情。
Gradle API:包含 Project、Task、Setting 等等。
可以看到,Gradle 的語法是以 groovy 為基礎的,而且它還有自己獨有的 API,所以我們可以把 Gradle 認作是一款編程框架,利用 Gradle 我們可以在編程中去實現項目構建過程中的所有需求。想要隨心所欲地使用 Gradle,我們必須提前掌握好 groovy。需要注意的是,Groovy 是一門語言,而 DSL 一種特定領域的配置文件,Gradle 是基于 Groovy 的一種框架工具,而 gradlew 則是 gradle 的一個兼容包裝工具。
Gradle 有以下優(yōu)勢:
- 靈活性:相對于 Maven、Ant 等構建工具,Gradle 提供了一系列的 API 讓我們有能力去修改或定制項目的構建過程。例如我們可以利用 Gradle 去動態(tài)修改生成的 APK 包名。
- 粒度性:使用 Maven、Ant 等構建工具時,我們的源代碼和構建腳本是獨立的,而且我們也不知道其內部的處理是怎樣的。但是 Gradle 則不同,它從源代碼的編譯、資源的編譯、到生成 APK 的過程中都是一個接一個來執(zhí)行的。此外,Gradle 構建的粒度細化到了每一個 task 之中。并且它所有的 Task 源碼都是開源的,在我們掌握了這一整套打包流程后,我們就可以通過修改它的 Task 去動態(tài)改變其執(zhí)行流程。例如 Tinker 框架的實現過程中,它通過動態(tài)地修改 Gradle 的打包過程生成 APK 的同時,也生成了各種補丁文件。
- 擴展性:Gradle 支持插件機制,所以我們可以復用這些插件,就如同復用庫一樣簡單方便。
兼容性:Gradle 不僅自身功能強大,而且它還能兼容所有的 Maven、Ant 功能,也就是說,Gradle 吸取了所有構建工具的長處。
可以看到,Gradle 相比于其它構建工具,其好處不言而喻,而其最核心的原因就是因為 Gradle 是一套編程框架。
二、Gradle 的生命周期
????所謂 Gradle 的生命周期,即 gradle 的執(zhí)行流程,也就是 Gradle 先執(zhí)行什么后執(zhí)行什么。我們看下它的流程圖:
可以看到,gradle 的執(zhí)行流程分了 初始化、配置、執(zhí)行 三個階段,上圖中的 project、task 我們接下來幾篇會詳細介紹。下面我們看看這幾個階段。

2.1 初始化階段
????初始化階段會讀取根工程中的 setting.gradle 中的 include 信息,確定有多少工程加入構建,然后會為每一個項目(build.gradle 腳本文件)創(chuàng)建一個個與之對應的 Project 實例,最終形成一個項目的層次結構。
????與初始化階段相關的腳本文件是 settings.gradle,而一個 settings.gradle 腳本對應一個 Settings 對象,我們最常用來聲明項目的層次結構的 include 就是 Settings 對象下的一個方法,在 Gradle 初始化的時候會構造一個 Settings 實例對象,以執(zhí)行各個 Project 的初始化配置。

????此外,在 settings.gradle 文件中,我們可以指定其它 project 的位置,這樣就可以將其它外部工程中的 moudle 導入到當前的工程之中了。示例代碼如下所示:
if (useStepMoudle) {
// 導入其它 App 的 step 步數模塊
include "step"
project(":step").projectDir = new File("../OtherApp/step")
}
2.2 配置階段
????配置階段的任務是執(zhí)行各項目下的 build.gradle 腳本,完成 Project 的配置,與此同時,會構造 Task 任務依賴關系圖以便在執(zhí)行階段按照依賴關系執(zhí)行 Task而在配置階段執(zhí)行的代碼通常來說都會包括以下三個部分的內容,如下所示:
- 1)、build.gralde 中的各種語句。
- 2)、閉包。
-
1)、Task 中的配置段語句
需要注意的是,執(zhí)行任何 Gradle 命令,在初始化階段和配置階段的代碼都會被執(zhí)行。
2.3 執(zhí)行階段
????在配置階段結束后,Gradle 會根據各個任務 Task 的依賴關系來創(chuàng)建一個有向無環(huán)圖,我們可以通過 Gradle 對象的 getTaskGraph 方法來得到該有向無環(huán)圖。并且當有向無環(huán)圖構建完成之后,所有 Task 執(zhí)行之前,我們可以通過 whenReady(groovy.lang.Closure) 或者 addTaskExecutionGraphListener(TaskExecutionGraphListener) 來接收相應的通知,其代碼如下所示:
gradle.getTaskGraph().addTaskExecutionGraphListener(new TaskExecutionGraphListener() {
@Override
void graphPopulated(TaskExecutionGraph taskExecutionGraph) {
}
})
然后,Gradle 構建系統(tǒng)會通過調用 gradle <任務名> 來執(zhí)行相應的各個任務。
可以看到,整個 Gradle 生命周期的流程包含如下 四個部分:
- 首先,解析 settings.gradle 來獲取模塊信息,這是初始化階段。
- 然后,配置每個模塊,配置的時候并不會執(zhí)行 task。
- 接著,配置完了以后,有一個重要的回調 project.afterEvaluate,它表示所有的模塊都已經配置完了,可以準備執(zhí)行 task 了。
- 最后,執(zhí)行指定的 task 及其依賴的 task。

2.4 生命周期監(jiān)聽
????上面我們學習了 Gradle 的執(zhí)行生命流程,下面我們在它的監(jiān)聽回調中做一些輸出。首先在項目根目錄的 build.gradle 中添加如下監(jiān)聽代碼:
//配置階段開始前的監(jiān)聽回調,也就是初始化階段和配置階段之間
beforeEvaluate {
println "準備執(zhí)行配置階段..."
}
//配置階段完成后的監(jiān)聽回調,執(zhí)行階段之前的監(jiān)聽
afterEvaluate {
println "配置階段執(zhí)行完畢..."
}
//gradle生命周期執(zhí)行完畢后的回調監(jiān)聽
this.gradle.buildFinished {
println "執(zhí)行階段執(zhí)行完畢..."
}
this.gradle.beforeProject{
}
this.gradle.afterProject{
}
在根目錄的 setting.gradle 中添加如下代碼:
include ':app'
println "初始化階段開始"
接下來我們執(zhí)行一個簡單的 gradle 命令:gradle clean
