1. 前言
前一段時間有人在我的邪教群裡問「剛學Android 不久,對Gradle 不懂,看了很多資料依然一知半解,希望張哥給講講Gradle 」,沒想到群裡很多人都響應,表示同感,有人在群組推薦了一本書,說看這本書就行了。說實在的,我不反對看書,但是我反對的是為了弄懂一個知識點就需要看一本書那效率也太低了,於是我良心張就隨口說了句“要不我在群裡開個講座給你們普及下Gradle 基本概念吧?”沒想到平時潛水的人全都出來了,然後紛紛回复“666...”,講真,剛說過我就後悔了,主要沒有那麼多時間,但是畢竟已經放開話了,當晚加班回到家,沒有一點準備就在群組裡給他們開始了長達一個多小時的普及工作,事後,出乎意料的大家一致反映效果很好,而且聽課的全都很認真,有很多有心的人把我在群組裡一字一句打的聊天記錄整理成了筆記分享在群組裡,我覺得這個主題可能對我的很多讀者也都很有幫助,所以我在群組裡整理的筆記的基礎上做了點補充與改進,希望這篇文章對你們有幫助!
2. 什麼是構建工具?
我們大家都知道Gradle 是一種構建工具,那麼什麼是構建工具呢?
網上一大堆的文字解釋我覺得很難理解,這裡我以咱們Android 開發來舉個例子吧。
我們以前開發都是用Eclipse ,而Eclipse 大家都知道是一種IDE (集成開發環境),最初是用來做Java 開發的,而Android 是基於Java 語言的,所以最初Google 還是希望Android 能在Eclipse 上進行開發,為了滿足這個需求,Google 開發了一個叫ADT (Android Developer Tools)的東西,相信以前從Eclipse 時代過來的對ADT 應該都不陌生,正是因為有了ADT ,從此我們只需要碼好程式碼,然後直接在Eclipse 上進行編譯、運行、簽署、打包等一系列流程,而這背後的工作都是ADT 的功勞。某種意義上 ADT 就是我們的建構工具。
而自 Google 推出 Android Studio 以來,就宣布默認使用 Gradle 來作為構建工具,並且之後放棄更新 ADT ,從此 Gradle 走入 Android 開發者的視野,而我也是在 AS 的 Beta 版開始接觸並學習 Gradle。
一般來說,建置工具除了以上提到的編譯、運行、簽名、打包等,還具備依賴管理的功能,什麼是依賴管理呢?還是拿Eclipse 來說,我們以前在Eclipse 上開發Android ,如果需要用到第三方函式庫的時候一般都是先下載jar 文件,然後把jar 檔案加入到libs 目錄,然後專案中就可以引用了。但是你不覺得這種管理方式很麻煩麼?假設第三方庫有更新,需要下載最新的Jar 文件,然後替換掉原來的,引用的庫少還好,一旦引用的第三方庫多,那簡直麻煩死,可以說這種方式只有依賴,而沒有管理。
現在大家不陌生的Gradle 引用第三方函式庫方式是這樣的:
compile 'com.android.support:support-v4:24.0.1'
類似這樣的依賴方式,是不是很方便?而且很直觀,直接可以看到來源位址,升級的話直接改下版本號碼就可以了,這就是所謂的依賴管理。
所以構建工具就是對你的專案進行編譯、運行、簽名、打包、依賴管理等一系列功能的合集,傳統的構建工具有Make、Ant、Maven、Ivy等,而Gradle 是新一代的自動化構建工具。
3. 什麼是Gradle ?
上面說了,Gradle 是新一代的自動化建構工具,它是一個獨立的項目,跟AS、Android 無關,官方網站:https://gradle.org/ , 類似Ant 、Maven這類建置工具都是基於xml 來進行描述的,很臃腫,而Gradle 採用的是一種叫做Groovy 的語言,語法跟Java 語法很像,但是是一種動態語言,而且在Java 基礎上做了不少改進,用起來更加簡潔、靈活,而且Gradle 完全兼容Maven、Ivy,這點基本上宣布了Maven、Ivy 可以被拋棄了,Gradle 的推出主要以Java 應用為主,當然目前還支持Android、 C、C++。
4. Gradle 與Android Studio 的關係
上面也提到,Gradle 跟Android Studio 其實沒有關係,但是Gradle 官方還是很看重Android 開發的,Google 在推出AS 的時候選中了Gradle 作為構建工具,為了支持Gradle 能在AS 上使用,Google 做了個AS 的插件叫Android Gradle Plugin ,所以我們能在AS 上使用Gradle 完全是因為這個插件的原因。在專案的根目錄有個 build.gradle 文件,裡面有這麼一句話程式碼:
classpath 'com.android.tools.build:gradle:2.1.2'
這個就是依賴 gradle 插件的程式碼,後面的版本號碼代表的是 android gradle plugin 的版本,而不是 Gradle 的版本,這個是 Google 定的,跟 Gradle 官方沒關係。關於android gradle plugin 的更多資訊可以到這裡查看,這裡列舉了android gradle plugin 每個版本的具體變化與具體功能:
http://tools.android.com/tech-docs/new-build-system
友情提示,需要科學上網!
5. Gradle Wrapper
現在默認現在默認一個項目,然後點擊AS 上的運行,預設就會直接幫你安裝Gradle ,我們不需要額外的安裝Gradle 了,但是其實這個Gradle 不是真正的Gradle ,他叫Gradle Wrapper ,意為Gradle 的包裝,什麼意思呢?假設我們本地有多個項目,一個是比較老的項目,還用著Gradle 1.0 的版本,一個是比較新的項目用了Gradle 2.0 的版本,但是你兩個項目肯定都想要同時運行的,如果你只裝了Gradle 1.0 的話那肯定不行,所以為了解決這個問題,Google 推出了Gradle Wrapper 的概念,就是他在你每個項目都配置了一個指定版本的Gradle ,你可以理解為每個Android專案本地都有一個小型的Gradle ,透過這個每個專案你可以支援用不同的Gradle 版本來建立專案。
理解了 Gradle Wrapper 的概念就好辦了,以下的所有操作都是基於 Gradle Wrapper 的。
預設我們在AS 上第一次創建專案會自動下載Gradle 的,這個過程很漫長,出奇的慢,但是第一次之後就ok了,接下來就是教大家用命令列測試下,請大家在終端機或AS 帶的終端上切換到所在專案的目錄,然後輸入./gradlew -v (win使用者直接輸入gradlew -v) ,即可以查看目前專案所用的gradle 的版本,gradlew 即為gradle wrapper 的縮寫,如果你是第一次執行命令列,那麼會出現一個下載的提示,緊接著會列印一個個的點,這個過程很漫長,依賴你的網速,時間幾分鐘到幾十分鐘不等。
有人有疑問,我AS 上明明已經可以正常運行該項目的,說明Gradle 已經下載過了,為什麼命令行還要再下載一次?我也一直有這個疑問,理論上是不該再下載的,但事實他就是要重新下載一次,我猜測可能是bug。
如果下載完成輸入 ./gradlew -v 出現如下結果,證明你的專案是ok的,否則就是你的專案配置有問題了。
6. Android 專案包含的Gradle 設定檔
這裡姑且以我很早在GitHub 開源的9GAG 專案為例,來稍微介紹下一個完整的Android 專案包含的基本Gradle 相關的設定檔:
紅色標記部分從上到下到下咱們來一步步分析:
9GAG/app/build.gradle
這個文件是app 文件夾下這個Module 的gradle 配置文件,也可以算是整個項目最主要的gradle 配置文件,具體裡面的配置文件以後再介紹。
9GAG/extras/ShimmerAndroid/build.gradle
每一個Module 都需要有一個gradle 配置文件,語法都是一樣,唯一不同的是開頭聲明的是
apply plugin: ‘com.android.library’ 9GAG/gradle
這個目錄下有個wrapper 文件夾,裡面可以看到有兩個文件,我們主要看下gradle-wrapper.properties 這個文件的內容:
可以看到裡面聲明了gradle 的目錄與下載路徑以及當前項目使用的gradle 版本,這些默認的路徑我們一般不會更改的,這個文件裡指明的gradle 版本不對也是許多導包不成功的原因之一。
9GAG/build.gradle
這個文件是整個專案的 gradle 基礎配置文件,預設的內容就是聲明了 android gradle plugin 的版本。
9GAG/settings.gradle
這個文件是全局的項目配置文件,裡面主要聲明一些需要加入gradle 的module,我們來看看9GAG 該文件的內容:
7. 如何正確導入下載的開源專案?
我們經常會在GitHub 發現一些優秀的開源項目,然後想要下載學習,然而第一步一般都是把源碼導入到AS 裡,然後運行起來看下效果,但是經常會運行失敗,這裡我來跟大家說下導入開源專案的正確姿勢:
下载一个Demo,先打开每个 module下的 gradle 文件,即 app 目录下的 build.gradle 以及各个 library 下的 build.gradle ,首先查看 compileSdkVersion 和 buildToolsVersion,因为有些时候你本地的版本和下载的版本不一致,那么就会导致失败。
然后就是检查 gradle-wrapper ,Google 有些时候要求不同的 AS 支持不同的 gradle 版本。比如 AS 1.0 的时候要求必须使用 gradle 1.x 的版本,等到 AS 2.0 的时候,Google 不支持 gradle1.x 的版本,这个时候你必须手动更新下 android gradle plugin 的版本,然后重新同步下。
检查以上两个地方基本就可以导入并运行了,如果还有其他问题,那可能就是环境或者项目本身的问题了。
8. 认识下几个命令
上面提到了,假设我们没有 IDE ,只有类似 Sublime、Atom、Vim这种轻量编辑器怎么办?那我们就没法开发 Android 了么?然而只要有构建工具,不需要 IDE 我们一样有办法开发,这个时候我们就需要用到几个有用的 Gradle 命令了:
./gradlew -v 版本号 ./gradlew clean 清除9GAG/app目录下的build文件夹 ./gradlew build 检查依赖并编译打包
这里注意的是 ./gradlew build 命令把 debug、release 环境的包都打出来,如果正式发布只需要打 Release 的包,该怎么办呢,下面介绍一个很有用的命令 assemble , 如
./gradlew assembleDebug 编译并打Debug包 ./gradlew assembleRelease 编译并打Release的包