本文默認讀者使用 macOShtml
以我本身爲例,剛開始接觸 Android 開發的時候,只是對 Java 開發有一些瞭解,對於 Android 開發的整個生態和技術棧只有一個模糊的認知。 缺少對 Gradle 的認知,在初級開發階段可能勉強能夠應付,只須要知道如何添加第三方依賴,如何調整 android block 中的配置基本上就夠了,可是隨着項目結構愈來愈複雜,默認提供的構建過程漸漸不能知足開發的需求,此時就要求開發者對 Gradle 的構建過程和原理有更深刻的瞭解,便於自定義個性化的構建過程。java
在閱讀完 《Gradle In Action》後,我發現 Android 工程的構建過程彷佛再也不那麼神祕了。 本文但願能從宏觀的角度帶剛接觸 Android 開發不久的同窗認識一下 Gradle,若是對 Gradle 工做原理感興趣,但願可以更加深刻了解,建議閱讀 《Gradle In Action》 這本書。android
隨着項目規模增大,軟件工程師須要考慮的事情會愈來愈多。成功構建並運行一個項目再也不像單文件的 HelloWorld 同樣簡單。隨着持續集成思想的普及,一次成功的構建可能分爲 checkStyle,Lint,編譯,單元測試,集成測試,代碼裁剪,代碼混淆,打包部署等多個步驟。若是項目中引用了第三方 lib,那麼第三方 lib 會有版本迭代,甚至多個第三方 lib 可能又依賴了不一樣版本的同一個第三方 lib,形成依賴版本衝突,事情會愈來愈複雜。咱們須要使每個 Commit 老是能構建出徹底相同的結果,Git 對於二進制文件的版本管理又不是那麼駕輕就熟,手動構建經常會引入人爲變數致使構建出錯。因此構建過程自動化迫在眉睫。git
Google 基於 Gradle 經過 Android Gradle Plugin 提供了自動化構建的工具,對開發者隱藏了大量的繁瑣的構建過程,暴露一些可被開發者配置的屬性,大大的簡化了 Android 項目管理的複雜度的同時又不失靈活性。web
在這裏列舉的構建工具不止能夠用來構建 Java 相關的項目。只要能表達出構建步驟,就可使用這些工具來進行項目構建。好比,你可使用 Gradle 來構建一個 iOS 的項目。api
The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. As a result, developers can get up and running with a Gradle project quickly without having to follow manual installation processes saving your company time and money.bash
構建工具也是須要版本迭代的,一個大的版本迭代可能不會提供向前的兼容性,也就是說,在 A 機器上和 B 機器上裝了兩個不一樣版本的 Gradle,結果可能致使同一個項目,在 A 的機器上能夠成功構建,而在 B 的機器上會構建失敗。 爲了不這個問題,保證每一個 Commit 總能構建出徹底相同的結果。Gradle 提供了 Gradle Wrapper,經過 Wrapper 運行 Gradle Task 的時候,會先檢查 gradle-wrapper.properties 中指定的位置下,指定版本的 Gradle 是否安裝,若是已經安裝,則將該 Gradle Task 交給 Gradle 處理。若是沒有安裝,則先下載安裝指定版本的 Gradle,而後再將 Gradle Task 交給 Gradle 處理。 gradlew 是一個 script,是 Gradle Wrapper 的入口,Windows 下是 gradlew.bat。 gradle-wrapper.jar 提供了 Gradlew Wrapper 的核心功能。oracle
目錄結構以下圖: app
以下圖所示是一個典型的使用 Gradle 進行構建的 Android 工程。 工程中包含兩個 Project:
gradlew projects
複製代碼
gradlew 是入口 Script, projects 其實是 Gradle 一個內置的 Task。 關於 Task 的概念,下面再解釋。 運行上面的命令,結果以下圖所示,能夠看到,通常咱們開發時修改 **app **只是一個子項目,RootProject 其實是 app 的上級目錄中的 TutorialAndroid。
Gradle 的構建過程分爲如下幾個階段: initialization -> configuration -> execution
A Task represents a single atomic piece of work for a build, such as compiling classes or generating javadoc.
A Task is made up of a sequence of Action objects. When the task is executed, each of the actions is executed in turn, by calling Action.execute(T). You can add actions to a task by calling Task.doFirst(org.gradle.api.Action) or Task.doLast(org.gradle.api.Action).
// 定義好 Task 以後,就能夠經過 `gradlew simpleTask` 來運行指定的 Task
task simpleTask {
doLast {
println "This is a simple task."
}
}
複製代碼
Gradle determines the subset of the tasks, created and configured during the configuration phase, to be executed. The subset is determined by the task name arguments passed to the gradle command and the current directory.
當一個 Project 的 Task 愈來愈複雜,或者多個項目都須要共用同一個 Task 的時候,爲了提升代碼複用性,能夠編寫 Plugin 將建立 Task 等邏輯封裝起來。
提升了代碼複用性的同時,還須要提供足夠的靈活性。Plugin 能夠經過 Extension 暴露一些可配置的屬性。這裏先不講,超綱了。
以上就是 Gradle 的工做過程。
使用 Proxy
在國內特殊的網絡環境,能夠經過設置 Proxy 或 Repo Mirror 的方式來提升下載依賴的 Library 的速度。
阿里提供的鏡像 maven.aliyun.com/mvn/view Gradle 使用 Java 的 Networking Properties 讀取 Proxy 參數。可供設置的參數參考如下文檔。
注意你的電腦中運行了多少 Gradle Daemon
Gradle 提供了 Daemon 機制來提升構建速度,可是 Gradle Daemon 的複用是有條件的。 若是恰巧給 Gradle Daemon 設置了一個比較大的 maximum heap size, 可能在開發的過程當中,多個 Daemon 會佔用過多的內存,影響電腦運行速度。除了前面給出的條件,還有兩點是以前開發過程當中遇到過的:
《Gradle In Action》 -- Benjamin Muschko
@Eric