一经窖、前言
????從明面上看画侣,Gradle 是一款強大的構(gòu)建工具,但 Gradle 不僅僅是一款強大的構(gòu)建工具配乱,它更像是一個編程框架搬泥。Gradle 的組成可以細(xì)分為如下三個方面:
????groovy 核心語法:包括 groovy 基本語法、閉包忿檩、數(shù)據(jù)結(jié)構(gòu)燥透、面向?qū)ο蟮鹊取?br>
Android DSL(build scrpit block):Android 插件在 Gradle 所特有的東西,我們可以在不同的 build scrpit block 中去做不同的事情兽掰。
Gradle API:包含 Project孽尽、Task、Setting 等等。
可以看到鸳吸,Gradle 的語法是以 groovy 為基礎(chǔ)的速勇,而且它還有自己獨有的 API,所以我們可以把 Gradle 認(rèn)作是一款編程框架养匈,利用 Gradle 我們可以在編程中去實現(xiàn)項目構(gòu)建過程中的所有需求都伪。想要隨心所欲地使用 Gradle,我們必須提前掌握好 groovy猬仁。需要注意的是先誉,Groovy 是一門語言,而 DSL 一種特定領(lǐng)域的配置文件诈闺,Gradle 是基于 Groovy 的一種框架工具漱病,而 gradlew 則是 gradle 的一個兼容包裝工具杨帽。
Gradle 有以下優(yōu)勢:
- 靈活性:相對于 Maven嗤军、Ant 等構(gòu)建工具,Gradle 提供了一系列的 API 讓我們有能力去修改或定制項目的構(gòu)建過程老客。例如我們可以利用 Gradle 去動態(tài)修改生成的 APK 包名震叮。
- 粒度性:使用 Maven、Ant 等構(gòu)建工具時尉间,我們的源代碼和構(gòu)建腳本是獨立的,而且我們也不知道其內(nèi)部的處理是怎樣的贪薪。但是 Gradle 則不同眠副,它從源代碼的編譯、資源的編譯霍弹、到生成 APK 的過程中都是一個接一個來執(zhí)行的娃弓。此外,Gradle 構(gòu)建的粒度細(xì)化到了每一個 task 之中钝计。并且它所有的 Task 源碼都是開源的齐佳,在我們掌握了這一整套打包流程后,我們就可以通過修改它的 Task 去動態(tài)改變其執(zhí)行流程本鸣。例如 Tinker 框架的實現(xiàn)過程中硅蹦,它通過動態(tài)地修改 Gradle 的打包過程生成 APK 的同時,也生成了各種補丁文件涮瞻。
- 擴展性:Gradle 支持插件機制假褪,所以我們可以復(fù)用這些插件,就如同復(fù)用庫一樣簡單方便宁否。
兼容性:Gradle 不僅自身功能強大缀遍,而且它還能兼容所有的 Maven域醇、Ant 功能冤寿,也就是說青伤,Gradle 吸取了所有構(gòu)建工具的長處。
可以看到号杠,Gradle 相比于其它構(gòu)建工具丰歌,其好處不言而喻,而其最核心的原因就是因為 Gradle 是一套編程框架眼溶。
二晓勇、Gradle 的生命周期
????所謂 Gradle 的生命周期绑咱,即 gradle 的執(zhí)行流程,也就是 Gradle 先執(zhí)行什么后執(zhí)行什么铝噩。我們看下它的流程圖:可以看到窿克,gradle 的執(zhí)行流程分了 初始化、配置具被、執(zhí)行 三個階段谋右,上圖中的 project改执、task 我們接下來幾篇會詳細(xì)介紹坑雅。下面我們看看這幾個階段。
2.1 初始化階段
????初始化階段會讀取根工程中的 setting.gradle 中的 include 信息终蒂,確定有多少工程加入構(gòu)建,然后會為每一個項目(build.gradle 腳本文件)創(chuàng)建一個個與之對應(yīng)的 Project 實例噪叙,最終形成一個項目的層次結(jié)構(gòu)霉翔。
????與初始化階段相關(guān)的腳本文件是 settings.gradle债朵,而一個 settings.gradle 腳本對應(yīng)一個 Settings 對象,我們最常用來聲明項目的層次結(jié)構(gòu)的 include 就是 Settings 對象下的一個方法臭杰,在 Gradle 初始化的時候會構(gòu)造一個 Settings 實例對象谚中,以執(zhí)行各個 Project 的初始化配置。
????此外将塑,在 settings.gradle 文件中蝌麸,我們可以指定其它 project 的位置来吩,這樣就可以將其它外部工程中的 moudle 導(dǎo)入到當(dāng)前的工程之中了。示例代碼如下所示:
if (useStepMoudle) {
// 導(dǎo)入其它 App 的 step 步數(shù)模塊
include "step"
project(":step").projectDir = new File("../OtherApp/step")
}
2.2 配置階段
????配置階段的任務(wù)是執(zhí)行各項目下的 build.gradle 腳本戚长,完成 Project 的配置怠苔,與此同時柑司,會構(gòu)造 Task 任務(wù)依賴關(guān)系圖以便在執(zhí)行階段按照依賴關(guān)系執(zhí)行 Task而在配置階段執(zhí)行的代碼通常來說都會包括以下三個部分的內(nèi)容,如下所示:
- 1)攒驰、build.gralde 中的各種語句玻粪。
- 2)诬垂、閉包伦仍。
-
1)充蓝、Task 中的配置段語句
需要注意的是,執(zhí)行任何 Gradle 命令悠垛,在初始化階段和配置階段的代碼都會被執(zhí)行娜谊。
2.3 執(zhí)行階段
????在配置階段結(jié)束后,Gradle 會根據(jù)各個任務(wù) Task 的依賴關(guān)系來創(chuàng)建一個有向無環(huán)圖湾趾,我們可以通過 Gradle 對象的 getTaskGraph 方法來得到該有向無環(huán)圖派草。并且當(dāng)有向無環(huán)圖構(gòu)建完成之后,所有 Task 執(zhí)行之前艺普,我們可以通過 whenReady(groovy.lang.Closure) 或者 addTaskExecutionGraphListener(TaskExecutionGraphListener) 來接收相應(yīng)的通知鉴竭,其代碼如下所示:
gradle.getTaskGraph().addTaskExecutionGraphListener(new TaskExecutionGraphListener() {
@Override
void graphPopulated(TaskExecutionGraph taskExecutionGraph) {
}
})
然后搏存,Gradle 構(gòu)建系統(tǒng)會通過調(diào)用 gradle <任務(wù)名> 來執(zhí)行相應(yīng)的各個任務(wù)。
可以看到缩焦,整個 Gradle 生命周期的流程包含如下 四個部分:
- 首先责静,解析 settings.gradle 來獲取模塊信息,這是初始化階段呻拌。
- 然后睦焕,配置每個模塊垃喊,配置的時候并不會執(zhí)行 task。
- 接著初家,配置完了以后乌助,有一個重要的回調(diào) project.afterEvaluate,它表示所有的模塊都已經(jīng)配置完了掖肋,可以準(zhǔn)備執(zhí)行 task 了赏参。
- 最后把篓,執(zhí)行指定的 task 及其依賴的 task。
2.4 生命周期監(jiān)聽
????上面我們學(xué)習(xí)了 Gradle 的執(zhí)行生命流程聋庵,下面我們在它的監(jiān)聽回調(diào)中做一些輸出。首先在項目根目錄的 build.gradle 中添加如下監(jiān)聽代碼:
//配置階段開始前的監(jiān)聽回調(diào)氧映,也就是初始化階段和配置階段之間
beforeEvaluate {
println "準(zhǔn)備執(zhí)行配置階段..."
}
//配置階段完成后的監(jiān)聽回調(diào)脱货,執(zhí)行階段之前的監(jiān)聽
afterEvaluate {
println "配置階段執(zhí)行完畢..."
}
//gradle生命周期執(zhí)行完畢后的回調(diào)監(jiān)聽
this.gradle.buildFinished {
println "執(zhí)行階段執(zhí)行完畢..."
}
this.gradle.beforeProject{
}
this.gradle.afterProject{
}
在根目錄的 setting.gradle 中添加如下代碼:
include ':app'
println "初始化階段開始"
接下來我們執(zhí)行一個簡單的 gradle 命令:gradle clean