Gradle 其實是很好用的
2017, Apr 14 by Tesla Ice Zhang
Gradle 是一款使用 Kotlin (划掉) Groovy 編寫的 JVM 構建工具,其易用性和 Maven 接近,而由於它描述邏輯采用的是 DSL 而不是辣眼睛的 xml , 股溝也欽定他作為 Android 的指定構建工具。
關於 Gradle
由於 Gradle 的構建過程高度依賴網絡,因此身在中國,在中國長城局域網的保護下的各位網絡條件是很不好的。
這就導致,明明一個賊好用的構建工具,把絕大多數的開發者都給坑慘了。
我作為一個在 2017 年 1 月對 Gradle 黑轉粉的 Gradle 用戶,在這里向同學們傳授中國 Gradle 的正確使用方式。
其實寫這篇博客我是很猶豫的,因為我在知乎已經看到過有人描述過我想寫的東西了,但是寫的很粗略,所以我決定再寫一次。
現在的問題就是,很多人沒有 VPN。這就導致你不能用 Proxifier 這種工具實現全局翻牆, 而像開燈這種行為又不能大幅影響命令行(作為一個有梯子的人,我是不清楚的,但是在我沒有梯子的時候,那叫一個痛苦)。
而他們面臨着寫 Android 項目的任務,想必很多人都體會過『只能在 Android Studio 里面構建, 切到命令行之后gradlew build
之后不知道它在下什么東西,反正就是不行』的感受。
其實呀,你們只是不知道 AS 在 build 的過程中,使用了自己夾帶的 gradle。我們現在要拒絕夾帶私貨,走向自由。
簡要介紹
首先我說明一下一個最普通的 gradle 項目的目錄結構:
root: gradle: wrapper: - gradle-wrapper.properties - gradle-wrapper.jar - build.gradle - settings.gradle - gradlew.bat - gradlew
這 6 個文件缺一不可,一般使用 Android Studio 新建 gradle 項目的時候會給你弄齊。
其中:
文件 | 最主要功能 |
---|---|
gradle-wrapper.properties | 用於指定 gradle 版本號 |
gradle-wrapper.jar | 和上面那個配套 |
build.gradle | 構建腳本,寫編譯的邏輯,依賴,各種你能想到的配置 |
settings.gradle | 指定工程名 |
gradlew.bat | Windows 下命令行構建時用的,一般不動它 |
gradlew | *nix 下命令行構建時用的,一般不動它 |
后兩個文件隨便找個 Gradle 項目(到處都是,不行也可以拿 AS 新建一個項目,自動加入)照抄即可,所以說我們要管的其實就四個文件。
settings.gradle
一般情況下,settings.gradle
里面就這個東西:
rootProject.name = 'lice'
就是指定項目名稱的,gradlew build
生成的 jar 包就是[項目名稱].jar
。
gradle-wrapper.properties
這個文件一般的內容就是:
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-[版本]-bin.zip
其實也只有一行需要注意,就是最后一行里面的版本。本文采用的 gradle 版本是3.0
,也就是說最后一行是:
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
早期 AS 默認的是2.1X
,我是不推薦的,已經過時很久啦。 根據知乎評論區提醒, AS 2.3 已經將 gradle 升級到了 3.3。
不過本文的教程適用於任何版本哦。
gradle-wrapper.jar
這個 jar 和上面的 properties 文件是配套的。
說一下以上兩個文件的一般的獲取方式(一般不直接寫,而是找到現成的):
在 GitHub 上隨便找個使用這個版本的 Gradle 的倉庫,然后download zip
,把它使用的這倆文件拿出來。
還有一個方法,就是
gradlew wrapper --gradle-version=3.5
這里順便提供一個3.0
版本的 gradle wrapper 的下載, 里面包含了 properties 文件和 jar 文件。
所以說現在只有build.gradle
需要注意了。這也是全文的重點。
如何配置 build.gradle
其實很簡單,舉個例子你們就民白了。
給一個項目加上 gradle 支持
一般情況下, Gradle 默認的項目結構是:
root: build: - 編譯輸出 src: main: java: - 代碼的包 kotlin: - Kotlin 代碼的包 test: java: - 測試代碼的包 kotlin: - Kotlin 測試代碼的包 gradle: wrapper: - gradle-wrapper.properties - gradle-wrapper.jar - build.gradle - settings.gradle - gradlew - gradlew.bat
但是我們先不管,畢竟我要帶你入坑,所以說我們要把一個原本不是這樣目錄結構的項目引入 Gradle 支持!
我們現在需要把這樣一個項目加上 gradle 支持:
root: demo: - demo 代碼的包 src: - 下面就是 Java 的 package 了,比如 org/frice/dsl 什么的 test: - 測試代碼的包
很明顯,這是個極其非主流的項目,它不符合 Gradle 的默認要求。
這其實就是我的一個個人項目,為了簡化教程,我把其中的一個子項目的構建給省略了。
現在我們先給他加上一些必須的文件(就是前面提到的除了build.gradle
之外的)
root: gradle: wrapper: - gradle-wrapper.properties - gradle-wrapper.jar demo: - demo 代碼的包 src: - 下面就是 Java 的 package 了,比如 org/frice/dsl 什么的 test: - 測試代碼的包 - settings.gradle - gradlew - gradlew.bat
然后我們給他加上一個build.gradle
。首先你要確認你的項目的如下信息分別是什么(其實就根據你的情況自己編)。
這里我給一個表格,並展示我在這個例子中為這些信息帶入的值。
信息 | 這個例子中的值 |
---|---|
包名 | org.frice |
項目名 | dsl |
依賴、版本 | JUnit 4.12 和 JetBrains annotation 15.0 |
版本 | 1.0 |
語言 | Java |
Java 版本 | 1.6 |
源代碼目錄 | /src |
測試代碼目錄 | /test 和/demo |
為什么選 Java6 呢?因為我這個項目其實是 2%的 Java 加 98%的 Kotlin ,那部分 Java 代碼沒有用到 Java8 的新特性, 我就選個兼容性更好的吧。
關於 Kotlin 的配置
這里說下 Kotlin 的配置(因為我這個項目是 Kotlin 的),不用 Kotlin 的同學可以跳過:
由於 Kotlin 的編譯需要加個 Kotlin 編譯器插件和一些庫,所以需要一些額外配置:
信息 | 這個例子中的值 |
---|---|
Kotlin 版本 | 1.1.1 |
編寫 build.gradle
首先我們根據如下模板填寫我們的信息:
group '[包名]' version '[版本]' buildscript { repositories { mavenCentral() } } apply plugin: 'java' sourceCompatibility = [語言版本] targetCompatibility = [語言版本] repositories { mavenCentral() } sourceSets { main.java.srcDirs += '[源代碼目錄]' test.java.srcDirs += '[測試代碼目錄]' } dependencies { compile group: '[依賴的包名]', name: '[依賴的名稱]', version: '[依賴版本]' testCompile group: '[測試代碼依賴的包名]', name: '[測試代碼依賴的名稱]', version: '[版本]' }
和 Kotlin 有關的信息
如果需要 Kotlin 支持,需要添加如下額外信息:
buildscript { ext.kotlin_version = '[Kotlin 版本]' dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'kotlin' sourceSets { main.kotlin.srcDirs += '[Kotlin 源碼目錄]' test.kotlin.srcDirs += '[Kotlin 源碼目錄]' } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" }
引入來自 JitPack 的依賴
JitPack是一個免費的遠端倉庫,我們如果需要引入這個倉庫的包的話,需要再加一句:
allprojects { repositories { maven { url 'https://jitpack.io' } } }
最后的結果
根據我們此處的信息(再合並 Kotlin、JitPack 相關的依賴),應該這樣填入:
group 'org.frice' version '1.0' allprojects { repositories { maven { url 'https://jitpack.io' } } } buildscript { ext.kotlin_version = '1.1.1' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'java' apply plugin: 'kotlin' sourceCompatibility = 1.6 targetCompatibility = 1.6 repositories { mavenCentral() } sourceSets { main.kotlin.srcDirs += 'src' main.java.srcDirs += 'src' test.kotlin.srcDirs += 'test' test.java.srcDirs += 'test' test.kotlin.srcDirs += 'demo' test.java.srcDirs += 'demo' } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" compile group: 'org.jetbrains', name: 'annotations', version: '15.0' testCompile group: 'junit', name: 'junit', version: '4.12' testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" }
嘗試命令行構建
然后我們在命令行運行(請一定要進行一次嘗試!):
- *nix :
chmod a+x gradlew
- Windows:
./gradlew build
然后你會發現它開始下載 gradle 的本體了。。。我們身處中國長城局域網,下載這個速度是極慢的。
Ctrl+C,把它停下吧。
你可能已經意識到了,接下來我們要解決一個巨大的問題,就是下載包的問題。
下載 Gradle 本體
我們現在把燈打開(腦補丑八怪歌詞),然后登陸Gradle 官網找到下載頁面 下載對應版本的 Gradle (或者你也可以從一些國內網站下載,比如 CSDN )。
我們現在使用的是 gradle 3.0 (如果你是從我給的那個鏈接下載的 Gradle wrapper 的話),於是我們需要下載 這個:
https://services.gradle.org/distributions/gradle-3.0-bin.zip
上面那個鏈接直接點就好了。
下載好后,放進這個目錄:
- Windows
C:/Users/[用戶名]/.gradle/wrapper/dists/gradle-3.0-bin/2z3tfybitalx2py5dr8rf2mti/
- *nix
/home/[計算機名]/.gradle/wrapper/distsgradle-3.0-bin/2z3tfybitalx2py5dr8rf2mti/
這個詭異的路徑會被自動創建,你只要執行一次gradlew build
它就會自動創建。因此我建議大家讓它自己創建,免得打錯。
然后重新回到剛才的項目目錄,執行剛才說過的指令,會看到它沒有在下載了,而是開始 unzip 我們剛才下載的
然后你就等編譯吧,我自己的編譯結果是這樣的(為了模擬第一次配置(就是剛手動下載完 gradle ), 我還特地刪除了我本地已經解壓好的包(但是我已經提前下載好 Kotlin 的 Gradle 插件了,這個也比較大,各位 Kotlin 猿請耐心等待!)):
編譯環境: Windows10 專業版
D:\git-repos\FriceEngine-DSL>gradlew build
Unzipping C:\Users\ice1000\.gradle\wrapper\dists\gradle-3.0-bin\2z3tfybitalx2py5dr8rf2mti\gradle-3.0-bin.zip to C:\Users\ice1000\.gradle\wrapper\dists\gradle-3.0-bin\2z3tfybitalx2py5dr8rf2mti
Starting a Gradle Daemon, 17 busy and 3 incompatible and 4 stopped Daemons could not be reused, use --status for details
:compileKotlin UP-TO-DATE
:compileJava UP-TO-DATE
:copyMainKotlinClasses UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestKotlin
Using kotlin incremental compilation
w: The '-d' option with a directory destination is ignored because '-module' is specified
:compileTestJava UP-TO-DATE
:copyTestKotlinClasses
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
:check
:build
BUILD SUCCESSFUL
Total time: 40.232 secs
編譯報錯的話,檢查一下是不是你的代碼本身就是錯的。
Enjoy Gradle!