天天看點

十分鐘了解Gradle

一、什麼是Gradle

簡單的說,Gradle是一個建構工具,它是用來幫助我們建構app的,建構包括編譯、打包等過程。我們可以為Gradle指定建構規則,然後它就會根據我們的“指令”自動為我們建構app。Android Studio中預設就使用Gradle來完成應用的建構。有些同學可能會有疑問:”我用AS不記得給Gradle指定過什麼建構規則呀,最後不還是能搞出來個apk。“ 實際上,app的建構過程是大同小異的,有一些過程是”通用“的,也就是每個app的建構都要經曆一些公共步驟。是以,在我們在建立工程時,Android Studio自動幫我們生成了一些通用建構規則,很多時候我們甚至完全不用修改這些規則就能完成我們app的建構。

有些時候,我們會有一些個性化的建構需求,比如我們引入了第三方庫,或者我們想要在通用建構過程中做一些其他的事情,這時我們就要自己在系統預設建構規則上做一些修改。這時候我們就要自己向Gradle”下指令“了,這時候我們就需要用Gradle能聽懂的話了,也就是Groovy。Groovy是一種基于JVM的動态語言,關于它的具體介紹,感興趣的同學可以文末參考”延伸閱讀“部分給出的連結。

我們在開頭處提到“Gradle是一種建構工具”。實際上,當我們想要更靈活的建構過程時,Gradle就成為了一個程式設計架構——我們可以通過程式設計讓建構過程按我們的意願進行。也就是說,當我們把Gradle作為建構工具使用時,我們隻需要掌握它的配置腳本的基本寫法就OK了;而當我們需要對建構流程進行高度定制時,就務必要掌握Groovy等相關知識了。限于篇幅,本文隻從建構工具使用者的角度來介紹Gradle的一些最佳實踐,在文末“延伸閱讀”部分給出了幾篇高品質的深入介紹Gradle的文章,其中包含了Groovy等知識的介紹。

二、Gradle的基本組分

1. Project與Task

在Gradle中,每一個待建構的工程是一個Project,建構一個Project需要執行一系列Task,比如編譯、打包這些建構過程的子過程都對應着一個Task。具體來說,一個apk檔案的建構包含以下Task:Java源碼編譯、資源檔案編譯、Lint檢查、打包以生成最終的apk檔案等等。

2. 插件

插件的核心工作有兩個:一是定義Task;而是執行Task。也就是說,我們想讓Gradle能正常工作,完成整個建構流程中的一系列Task的執行,必須導入合适的插件,這些插件中定義了建構Project中的一系列Task,并且負責執行相應的Task。

在建立工程的app子產品的build.gradle檔案的第一行,往往都是如下這句:

這句話的意思就是應用“com.android.application“這個插件來建構app子產品,app子產品就是Gradle中的一個Project。也就是說,這個插件負責定義并執行Java源碼編譯、資源檔案編譯、打包等一系列Task。實際上"com.android.application"整個插件中定義了如下4個頂級任務:

assemble: 建構項目的輸出(apk)

check: 進行校驗工作

build: 執行assemble任務與check任務

clean: 清除項目的輸出

當我們執行一個任務時,會自動執行它所依賴的任務。比如,執行assemble任務會執行assembleDebug任務和assembleRelease任務,這是因為一個Android項目至少要有debug和release這兩個版本的輸出。

3. Gradle配置檔案

我們在Android Studio中建立一個工程,可以得到如下的工程結構圖:

十分鐘了解Gradle

上面我們說過,Android Studio中的一個Module即為Gradle中的一個Project。上圖的app目錄下,存在一個build.gradle檔案,代表了app Module的建構腳本,它定義了應用于本子產品的建構規則。我們可以看到,工程根目錄下也存在一個build.gradle檔案,它代表了整個工程的建構,其中定義了适用于這個工程中所有子產品的建構規則。

接下來我們介紹一下上圖中其他幾個Gradle配置檔案:

gradle.properties: 從它的名字可以看出,這個檔案中定義了一系列“屬性”。實際上,這個檔案中定義了一系列供build.gradle使用的常量,比如keystore的存儲路徑、keyalias等等。

gradlew與gradlew.bat: gradlew為Linux下的shell腳本,gradlew.bat是Windows下的批處理檔案。gradlew是gradle wrapper的縮寫,也就是說它對gradle的指令進行了包裝,比如我們進入到指定Module目錄并執行“gradlew.bat assemble”即可完成對目前Module的建構(Windows系統下)。

local.properties: 從名字就可以看出來,這個檔案中定義了一些本地屬性,比如SDK的路徑。

settings.gradle: 假如我們的項目包含了不隻一個Module時,我們想要一次性建構所有Module以完成整個項目的建構,這時我們需要用到這個檔案。比如我們的項目包含了ModuleA和ModuleB這兩個子產品,則這個檔案中會包含這樣的語句:include ':ModuleA', ':ModuleB'。

4. 建構腳本

首先我們來看一下工程目錄下的build.gradle,它指定了真個整個項目的建構規則,它的内容如下:

我們再來簡單介紹下app子產品的build.gradle的内容:

三、常見配置

整個工程的build.gradle通常不需我們改動,這裡我們介紹下一些對子產品目錄下build.gradle檔案的常見配置。

1. 依賴第三方庫

當我們的項目中用到了了一些第三方庫時,我們就需要進行一些配置,以保證能正确導入相關依賴。設定方法很簡單,比如我們在app子產品中中用到了Fresco,隻需要在build.gradle檔案中的dependencies塊添加如下語句:

這樣一來,Gradle會自動從jcenter倉庫下載下傳我們所需的第三方庫并導入到項目中。

2. 導入本地jar包

在使用第三方庫時,除了像上面那樣從jcenter倉庫下載下傳,我們還可以導入本地的jar包。配置方法也很簡單,隻需要先把jar檔案添加到app\libs目錄下,然後在相應jar檔案上單擊右鍵,選擇“Ad As Library”。然後在build.gradle的dependencies塊下添加如下語句:

實際上我們可以看到,系統為我們建立的build.gradle中就已經包含了如下語句:

這句話的意思是,将libs目錄下的所有jar包都導入。是以實際上我們隻需要把jar包添加到libs目錄下并“Ad As Library"即可。

3. 依賴其它子產品

假設我們的項目包含了多個子產品,并且app子產品依賴other子產品,那麼我們隻需app\build.gradle的denpendencies塊下添加如下語句:

4. 建構輸出為aar檔案

通常我們建構的輸出目标都是apk檔案,但如果我們的目前項目時Android Library,我們的目标輸出就是aar檔案。要想達到這個目的也很容易,隻需要把build.gradle的第一句改為如下:

這話表示我們使用的插件不再是建構Android應用的插件,而是建構Android Library的插件,這個插件定義并執行用于建構Android Library的一系列Task。

5. 自動移除不再使用的資源

隻需進行如下配置:

6. 忽略Lint錯誤

在我們建構Android項目的過程中,有時候會由于Lint錯誤而終止。當這些錯誤來自第三方庫中時,我們往往想要忽略這些錯誤進而繼續建構程序。這時候,我們可以隻需進行如下配置:

7. 內建簽名配置

在建構release版本的Android項目時,每次都手動導入簽名檔案,鍵入密碼、keyalias等資訊十分麻煩。通過将簽名配置內建到建構腳本中,我們就不必每次建構發行版本時都手動設定了。具體配置如下:

真實開發中,我們不應該把密碼等資訊直接寫到build.gradle中,更好的做法是放在gradle.properties中設定:

然後在build.gradle中直接引用即可:

關于Gradle的其他配置方法大家可以參考“延伸閱讀”部分的“Gradle最佳實踐”。

繼續閱讀