Gradle Wrapper 詳解
前面一小節(jié)《Android項(xiàng)目Gradle配置詳解》中我們介紹了 Android 項(xiàng)目的目錄及 Gradle 配置,我們提到有個(gè)目錄是/gradle/wrapper
。今天這篇文章我們來學(xué)習(xí) Gradle Wrapper。通過這篇文章我們將了解什么是 Gradle Wrapper?為什么需要用 Gradle Wrapper?以及 Gradle Wrapper 的重要性。
1. 什么是 Gradle Wrapper?
關(guān)于“什么是 Gradle Wrapper?”這個(gè)問題在官網(wǎng)是這么定義的:
The recommended way to execute any Gradle build is with the help of the Gradle Wrapper (in short just “Wrapper”). 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.—官方
我們翻譯過來大致意思就是:官方建議任何 Gradle 構(gòu)建方法在 Gradle Wrapper 幫助下運(yùn)行。Gradle Wrapper 它是一個(gè)腳本,調(diào)用了已經(jīng)聲明的 Gradle 版本,并且我們編譯時(shí)需要事先下載它。所以,開發(fā)者能夠快速的啟動(dòng)并且運(yùn)行 Gradle 項(xiàng)目,不用再手動(dòng)安裝,從而節(jié)省了時(shí)間成本。
我們可以稱 Gradle Wrapper 為 Gradle 包裝器,是將 Gradle 再次包裝。讓所有的 Gradle 構(gòu)建方法在 Gradle 包裝器的幫助下運(yùn)行。
2. 為什么需要 Gradle Wrapper?
其實(shí)關(guān)于這個(gè)問題在介紹 Gradle Wrapper 的時(shí)候已經(jīng)回答了。下面我們通過一個(gè)開發(fā)生活中的案例來形象的介紹一下。我們?nèi)粘i_發(fā)中肯定都是一個(gè)團(tuán)隊(duì)在開發(fā),如果沒有 Gradle Wrapper 的話,那么團(tuán)隊(duì)中每來一個(gè)新同事,就需要在電腦中安裝 Gradle 環(huán)境。但是有時(shí)候我們不同項(xiàng)目 Gradle 的版本又是不一樣的,這就為我們的開發(fā)工作帶來了不便。
于是乎 Gradle 就提供了 Gradle Wrapper,可以讓我們的電腦中不安裝 Gradle 環(huán)境也可以運(yùn)行 Gradle 項(xiàng)目。這就是上面官方介紹中所說的 Gradle 是一個(gè)腳本,調(diào)用事先聲明的 Gradle 版本,編譯前去下載它,這樣我們的電腦中就不用再去手動(dòng)安裝 Gradle 環(huán)境了,從而間接的提高了我們的開發(fā)效率。
從前面一節(jié)課我們可以看到 AndroidStudio 創(chuàng)建項(xiàng)目時(shí)默認(rèn)會(huì)創(chuàng)建 Gradle Wrapper 目錄,這也就是我們不用去手動(dòng)安裝 Gradle 環(huán)境的原因。Gradle Wrapper 的工作流程圖如下:
它的流程主要分為 3 步走:
首先當(dāng)我們剛創(chuàng)建的時(shí)候,如果指定的版本沒有被下載,就先會(huì)去 Gradle 的服務(wù)器中下載對應(yīng)版本的壓縮包,下載完成后需要先進(jìn)行解壓縮并且執(zhí)行批處理文件,后續(xù)項(xiàng)目每次構(gòu)建都會(huì)重用這個(gè)解壓過的 Gradle 版本。
3. 如何構(gòu)建 Gradle Wrapper?
要想構(gòu)建 Gradle Wrapper 就必須本地先配置了 Gradle 環(huán)境變量,具體的配置方法可以參考《構(gòu)建自己的 Gradle 工程》中關(guān)于 Gradle 環(huán)境變量的配置。Gradle 的命令中已經(jīng)內(nèi)置了 wrapper 命令,其實(shí)就是執(zhí)行 warpper 任務(wù)。該任務(wù)就是生成我們前面說的 gradle 文件夾及它的子目錄 wrapper 文件夾。在根目錄下我們先刪掉 gradle 文件夾,然后在項(xiàng)目根目錄執(zhí)行gradle wrapper
命令。
C:\Users\LeiQi PC\Documents\MyApplication>gradle wrapper
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.0.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
我們會(huì)看到會(huì)重新生成 Gradle 文件夾,目錄結(jié)構(gòu)如我們上節(jié)中的一樣如下。
這兩個(gè)文件的含義如下:
- gradle-wrapper.jar: 既然是 jar 包,那么它肯定是包含了 Gradle 運(yùn)行時(shí)的邏輯代碼;
- gradle-wrapper.properties: 這個(gè)文件主要負(fù)責(zé)配置 Gradle wrapper 運(yùn)行時(shí)的屬性文件,聲明具體使用哪個(gè)版本的 Gradle。
4. 配置 Gradle Wrapper
我們上面說gradle-wrapper.properties
文件指明了 Gradle 的版本號,和 Gradle 運(yùn)行時(shí)的行為屬性文件。下面我們具體看下這個(gè)文件的內(nèi)容:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
關(guān)于每個(gè)字段的意思如下:
- distributionBase: Gradle 解包后存儲的父目錄;
- distributionPath:
distributionBase
指定目錄的子目錄。distributionBase+distributionPath
就是 Gradle 解包后的存放的具體目錄; - distributionUrl: Gradle 指定版本的壓縮包下載地址;
- zipStoreBase: Gradle 壓縮包下載后存儲父目錄;
- zipStorePath:
zipStoreBase
指定目錄的子目錄。zipStoreBase+zipStorePath
就是 Gradle 壓縮包的存放位置。
Tips: 這里我們需要關(guān)注 distributionUrl 這個(gè)字段,我們經(jīng)常會(huì)遇到升級 AndroidStudio 后項(xiàng)目初始化編譯緩慢的問題。這個(gè)問題就是升級后 AndroidStudio 會(huì)自定改掉
gradle-wrapper.properties
里面 distributionUrl 字段 Gradle 的版本號。遇到這個(gè)問題我們不慌,可以將該字段改為我們本地已經(jīng)下載好的版本號。修改完成后重啟 AndroidStudio 就可以很快編譯通過了。
5. 使用 Gradle Wrapper 下載 Gradle
使用 Gradle wrapper 下載 Gradle 我們可以點(diǎn)擊 AS 界面上的同步按鈕,也可以使用 gradlew 命令來執(zhí)行 gradle 命令來下載,下面以 Windows 系統(tǒng)為例,我本地distributionUrl
配置的 Gradle 版本是gradle-6.0.1-bin.zip
,我們現(xiàn)在改為gradle-5.0-all.zip
版本,執(zhí)行clean命令,看看有沒有下載 5.0 版本下載:
C:\Users\LeiQi PC\Documents\MyApplication>gradlew clean
Downloading https://services.gradle.org/distributions/gradle-5.0-all.zip
............10%............20%.............30%............40%............50%.............60%............70%.............80%............90%............100%
Welcome to Gradle 5.0!
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 up-to-date
我們看到這里已經(jīng)下載了 gradle 5.0 版本,那么按照前面所說,再次執(zhí)行命令,直接調(diào)用本地的 Gradle,不會(huì)去下載我們來看下:
C:\Users\LeiQi PC\Documents\MyApplication>gradlew clean
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.0/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 up-to-date
我們看到這里沒有再去下載 Gradle 版本了而是直接使用上次下載的緩存下來的。
6. 升級Gradle Wrapper
升級 Gradle Wrapper 有 2 種方式:
- 一種是我們前面演示的,直接修改
distributionUrl
字段,然后執(zhí)行Gradle 命令或是點(diǎn)擊同步按鈕同步。 - 還有一種就是執(zhí)行 gradlew 命令
gradlew wrapper –-gradle-version [version]
這里我們將 5.0 升級為最新版 6.0.1.
C:\Users\LeiQi PC\Documents\MyApplication>gradlew wrapper --gradle-version 6.0.1
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.0.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 1s
1 actionable task: 1 up-to-date
然后我們使用gradlew -v
查看當(dāng)前的 Gradle 版本號:
C:\Users\LeiQi PC\Documents\MyApplication>gradlew -v
------------------------------------------------------------
Gradle 6.0.1
------------------------------------------------------------
Build time: 2019-11-18 20:25:01 UTC
Revision: fad121066a68c4701acd362daf4287a7c309a0f5
Kotlin: 1.3.50
Groovy: 2.5.8
Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM: 1.8.0_221 (Oracle Corporation 25.221-b11)
OS: Windows 10 10.0 amd64
我們看到此時(shí)版本號已經(jīng)升級為 6.0.1了。
7. 自定義 Gradle Wrapper
AndroidStudio 中 Gradle 內(nèi)置了 Wrapper 任務(wù),因此我們可以直接執(zhí)行 Gradle wrapper。既然他是一個(gè)任務(wù),那么我們其實(shí)也可以自定義這個(gè)任務(wù),定義該任務(wù)我們可以指定上面gradle-wrapper.properties
文件中的字段,如下所示:
task wrapper(type: Wrapper) {
gradleVersion = '6.0.1'
distributionUrl = '../../gradle-6.0.1-bin.zip'
distributionPath=wrapper/dists
}
Tips: 這里自定義 wrapper 時(shí),我們可以將
distributionUrl
字段指定為本地的目錄。
8. 小結(jié)
這篇文章我們學(xué)習(xí)了 Gradle Wrapper,已經(jīng)它的重要性和一些基本的操作。關(guān)于這個(gè)平時(shí)我們基本上用不到,所以只需要理解其原理就行了,唯一要注意的就是我們升級 AndroidStudio 后,項(xiàng)目第一次打開初始化編譯換慢,這時(shí)候是因?yàn)橄到y(tǒng)更改了 gradle wrapper 中的 Gradle 版本,由于 Gradle 服務(wù)器在國外國內(nèi)訪問受限,所以我們可以將 Gradle 版本修改為之前本地下載過的版本號,然后重啟 APP 就好了。