看似無用,實則重要的Gradle Wrapper
原文來自微信公眾號:劉望舒
1.為什麼需要Gradle Wrapper
Gradle Wrapper稱為Gradle包裝器,是對Gradle的一層包裝。為什麼需要Gradle Wrapper呢?比如在一個開發團隊中,如果每進來一個成員,都需要在計算機中安裝Gradle,這個時候執行Gradle的環境和版本就會對構建結果帶來不確定性。針對這個問題,Gradle提供了一個解決方案,那就是Gradle Wrapper,它是一個指令碼,可以在計算機沒有安裝Gradle的情況下執行Gradle構建,並且能夠指定Gradle的版本,開發人員可以快速啟動並執行Gradle專案,而不必手動安裝,這樣就標準化了專案,從而提高了開發效率。AS在新建專案時會自帶Gradle Wrapper,這也是我們很少去單獨去下載安裝Gradle的原因。Gradle Wrapper的工作流程如下圖所示。

在這裡插入圖片描述
當使用Gradle Wrapper啟動Gradle時,如果指定版本的Gradle沒有被下載關聯,會先從Gradle官方倉庫下載該版本Gradle到使用者本地,進行解包並執行批處理檔案。後續的構建執行都會重用這個解包的執行時安裝程式。
2.構建Gradle Wrapper
首先要確保計算機中配置好了Gradle的環境,沒有的話可以參考Android Gradle(二)Gradle入門前奏這篇文章去配置Gradle的環境。
Gradle已經內建了Wrapper Task,執行Wrapper Task就可以在專案目錄中生成Gradle Wrapper的目錄檔案。在專案根目錄執行gradle wrapper就可以了。
$ gradle wrapper > Task :wrapper BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed
這時會在專案根目錄中生成如下檔案:
├── gradle │└── wrapper │├── gradle-wrapper.jar │└── gradle-wrapper.properties ├── gradlew └── gradlew.bat
每個檔案的含義如下:
- gradle-wrapper.jar :包含Gradle執行時的邏輯程式碼。
- gradle-wrapper.properties :負責配置包裝器執行時行為的屬性檔案,用來配置使用哪個版本的Gradle等屬性。
- gradlew:Linux平臺下,用於執行Gralde命令的包裝器指令碼。
- gradlew.bat:Windows平臺下,用於執行Gralde命令的包裝器指令碼。
當生成好了上面的這些目錄與檔案後,使用者就可以將工程push到遠端,當其他使用者clone下來後就可以直接進行專案的構建,節省了使用者單獨下載Gradle的時間,並且可以確保Gradle版本的一致。
也可以用gradle命令列選項,來生成gradle wrapper。
--gradle-version:用於下載和執行指定的gradle版本。
--distribution-type:指定下載Gradle發行版的型別,可用選項有bin和all,預設值是bin,-bin發行版只包含執行時,但不包含原始碼和文件。
--gradle-distribution-url: 指定下載Gradle發行版的完整URL地址。
--gradle-distribution-sha256-sum:使用的SHA 256雜湊和驗證下載的Gradle發行版。
比如使用命令列:gradle wrapper --gradle-version 4.2.1 --distribution-type all,就可以生成版本為4.2.1的包裝器,並使用-all發行版。
3.配置Gradle Wrapper
gradle-wrapper.properties是Gradle Wrapper的屬性檔案,用來配置Gradle Wrapper,Gradle 4.2.1版本對應的gradle-wrapper.properties如下所示。
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
欄位的含義如下:
- distributionBase:Gradle解包後儲存的主目錄。
- distributionPath:distributionBase指定目錄的子目錄。
- distributionBase+distributionPath就是Gradle解包後的存放位置。
- distributionUrl:Gradle發行版壓縮包的下載地址。
- zipStoreBase:Gradle壓縮包儲存主目錄。
- zipStorePath:zipStoreBase指定目錄的子目錄。
- zipStoreBase+zipStorePath就是Gradle壓縮包的存放位置。
這裡我們最需要關注的是distributionUrl這個欄位,如果官方的地址下載不了或者緩慢,可以將這個地址換為其他的映象地址,或者乾脆把Gradle發行版壓縮包放在伺服器上以供下載。
4.使用Gradle Wrapper
使用Gradle Wrapper不是用Gradle命令,而是用gradlew和gradlew.bat指令碼。在build.gradle中加入如下語句:
task test { doLast { println 'Hello world!' } }
以Windows平臺為例,我們進入專案所在的根目錄執行gradlew.bat test:
f:\app>gradlew.bat test Downloading https://services.gradle.org/distributions/gradle-4.2.1-bin.zip ................................................................... Starting a Gradle Daemon (subsequent builds will be faster) > Task :test Hello world!
如果計算機中沒有Gradle發行版,Gradle包裝器會將Gradle發行版壓縮包下載到本地中並進行解壓,比如在我計算機中的儲存路徑為:
C:\Users\52501.gradle\wrapper\dists\gradle-4.2.1-bin\dajvke9o8kmaxbu0kc5gcgeju\gradle-4.2.1。 如果此後Gradle屬性檔案的distributionUrl屬性不變,就會一直使用本地的Gradle發行版。如果我們再次執行gradlew.bat test,就會和呼叫Gradle命令一樣: f:\app>gradlew.bat test Starting a Gradle Daemon (subsequent builds will be faster) > Task :test Hello world!
5.升級Gradle Wrapper
升級Gradle Wrapper有兩種方式,一種是設定Gradle屬性檔案的distributionUrl屬性,第二種是通過執行wrapper任務,推薦使用第二種方式。當前本地的Gradle版本為4.2.1,我想升級為5.1.1,只需要執行gradlew wrapper --gradle-version 5.1.1命令就可以了。
f:\app>gradlew wrapper --gradle-version 5.1.1 BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed 執行gradlew -v命令來檢查Gradle的版本。 f:\app>gradlew -v Downloading https://services.gradle.org/distributions/gradle-5.1.1-bin.zip ................................................................................. Unzipping C:\Users\52501\.gradle\wrapper\dists\gradle-5.1.1-bin\90y9l8txxfw1s2o6ctiqeruwn\gradle-5.1.1-bin.zip to C:\Users\52501\.gradle\wrapper\dists\gradle-5.1.1-bin\90y9l8txxfw1s2o6ctiqeruwn Welcome to Gradle 5.1.1! Here are the highlights of this release: - Control which dependencies can be retrieved from which repositories - Production-ready configuration avoidance APIs For more details see https://docs.gradle.org/5.1.1/release-notes.html ------------------------------------------------------------ Gradle 5.1.1 ------------------------------------------------------------ Build time:2019-01-10 23:05:02 UTC Revision:3c9abb645fb83932c44e8610642393ad62116807 Kotlin DSL:1.1.1 Kotlin:1.3.11 Groovy:2.5.4 Ant:Apache Ant(TM) version 1.9.13 compiled on July 10 2018 JVM:1.8.0_191 (Oracle Corporation 25.191-b12) OS:Windows 10 10.0 amd64
由於本地不是Gradle 5.1.1,會將下載下來的Gradle壓縮包儲存起來並進行解包,具體的見上面的列印日誌。
6.自定義Gradle Wrapper
Gradle已經內建了Wrapper Task,因此構建Gradle Wrapper會生成Gradle Wrapper的屬性檔案,這個屬性檔案可以通過自定義Wrapper Task來設定。比如我們想要修改要下載的Gralde版本為4.2.1,可以這麼設定:
task wrapper(type: Wrapper) { gradleVersion = '4.2.1' }
也可以設定Gradle發行版壓縮包的下載地址和Gradle解包後的本地儲存路徑等配置。
task wrapper(type: Wrapper) { gradleVersion = '4.2.1' distributionUrl = '../../gradle-4.2.1-bin.zip' distributionPath=wrapper/dists }
distributionUrl屬性可以設定為本地的專案目錄,你也可以設定為網路地址。