20年第45周:十分鐘理解Greadle

一、什么是Gradle

簡單的說侄旬,Gradle是一個構(gòu)建工具,它是用來幫助我們構(gòu)建app的煌妈,構(gòu)建包括編譯儡羔、打包等過程。我們可以為Gradle指定構(gòu)建規(guī)則璧诵,然后它就會根據(jù)我們的“命令”自動為我們構(gòu)建app汰蜘。Android Studio中默認(rèn)就使用Gradle來完成應(yīng)用的構(gòu)建。有些同學(xué)可能會有疑問:”我用AS不記得給Gradle指定過什么構(gòu)建規(guī)則呀之宿,最后不還是能搞出來個apk族操。“ 實(shí)際上比被,app的構(gòu)建過程是大同小異的色难,有一些過程是”通用“的,也就是每個app的構(gòu)建都要經(jīng)歷一些公共步驟等缀。因此枷莉,在我們在創(chuàng)建工程時,Android Studio自動幫我們生成了一些通用構(gòu)建規(guī)則尺迂,很多時候我們甚至完全不用修改這些規(guī)則就能完成我們app的構(gòu)建笤妙。

有些時候冒掌,我們會有一些個性化的構(gòu)建需求,比如我們引入了第三方庫蹲盘,或者我們想要在通用構(gòu)建過程中做一些其他的事情股毫,這時我們就要自己在系統(tǒng)默認(rèn)構(gòu)建規(guī)則上做一些修改。這時候我們就要自己向Gradle”下命令“了召衔,這時候我們就需要用Gradle能聽懂的話了铃诬,也就是Groovy。Groovy是一種基于JVM的動態(tài)語言薄嫡,關(guān)于它的具體介紹氧急,感興趣的同學(xué)可以文末參考”延伸閱讀“部分給出的鏈接。

我們在開頭處提到“Gradle是一種構(gòu)建工具”毫深。實(shí)際上吩坝,當(dāng)我們想要更靈活的構(gòu)建過程時,Gradle就成為了一個編程框架——我們可以通過編程讓構(gòu)建過程按我們的意愿進(jìn)行哑蔫。也就是說钉寝,當(dāng)我們把Gradle作為構(gòu)建工具使用時,我們只需要掌握它的配置腳本的基本寫法(可以理解為寫配置腳本)就OK了闸迷;而當(dāng)我們需要對構(gòu)建流程進(jìn)行高度定制時嵌纲,就務(wù)必要掌握Groovy等相關(guān)知識了。限于篇幅腥沽,本文只從構(gòu)建工具使用者的角度來介紹Gradle的一些最佳實(shí)踐逮走,在文末“延伸閱讀”部分給出了幾篇高質(zhì)量的深入介紹Gradle的文章,其中包含了Groovy等知識的介紹今阳。

二师溅、Gradle的基本組分

1. Project與Task

在Gradle中,每一個待構(gòu)建的工程是一個Project盾舌,構(gòu)建一個Project需要執(zhí)行一系列Task墓臭,比如編譯、打包這些構(gòu)建過程的子過程都對應(yīng)著一個Task妖谴。具體來說窿锉,一個apk文件的構(gòu)建包含以下Task:Java源碼編譯、資源文件編譯膝舅、Lint檢查嗡载、打包以生成最終的apk文件等等。

2. 插件

插件的核心工作有兩個:一是定義Task仍稀;二是執(zhí)行Task鼻疮。具體而言,我們想讓Gradle能正常工作琳轿,完成整個構(gòu)建流程中的一系列Task的執(zhí)行判沟,必須導(dǎo)入合適的插件,這些插件中定義了構(gòu)建Project中的一系列Task崭篡,并且負(fù)責(zé)執(zhí)行相應(yīng)的Task挪哄。

在新建工程的app模塊的build.gradle文件的第一行,往往都是如下這句:

<pre style="margin: 0px; padding: 0px;">apply plugin: 'com.android.application'</pre>

這句話的意思就是應(yīng)用“com.android.application“這個插件來構(gòu)建app模塊琉闪,app模塊就是Gradle中的一個Project迹炼。也就是說,這個插件負(fù)責(zé)定義并執(zhí)行Java源碼編譯颠毙、資源文件編譯斯入、打包等一系列Task。實(shí)際上"com.android.application"整個插件中定義了如下4個頂級任務(wù):

  • assemble: 構(gòu)建項目的輸出(apk)

  • check: 進(jìn)行校驗工作

  • build: 執(zhí)行assemble任務(wù)與check任務(wù)

  • clean: 清除項目的輸出

當(dāng)我們執(zhí)行一個任務(wù)時蛀蜜,會自動執(zhí)行它所依賴的任務(wù)刻两。比如,執(zhí)行assemble任務(wù)會執(zhí)行assembleDebug任務(wù)和assembleRelease任務(wù)滴某,這是因為一個Android項目至少要有debug和release這兩個版本的輸出磅摹。

3. Gradle配置文件

我們在Android Studio中新建一個工程,可以得到如下的工程結(jié)構(gòu)圖:

image

上面我們說過霎奢,Android Studio中的一個Module即為Gradle中的一個Project户誓。上圖的app目錄下,存在一個build.gradle文件幕侠,代表了app Module的構(gòu)建腳本帝美,它定義了應(yīng)用于本模塊的構(gòu)建規(guī)則。我們可以看到晤硕,工程根目錄下也存在一個build.gradle文件悼潭,它代表了整個工程的構(gòu)建,其中定義了適用于這個工程中所有模塊的構(gòu)建規(guī)則窗骑。

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

  • gradle.properties: 從它的名字可以看出女责,這個文件中定義了一系列“屬性”。實(shí)際上创译,這個文件中定義了一系列供build.gradle使用的常量抵知,比如keystore的存儲路徑、keyalias等等软族。

  • gradlew與gradlew.bat: gradlew為Linux下的shell腳本刷喜,gradlew.bat是Windows下的批處理文件。gradlew是gradle wrapper的縮寫立砸,也就是說它對gradle的命令進(jìn)行了包裝掖疮,比如我們進(jìn)入到指定Module目錄并執(zhí)行“gradlew.bat assemble”即可完成對當(dāng)前Module的構(gòu)建(Windows系統(tǒng)下)。

  • local.properties: 從名字就可以看出來颗祝,這個文件中定義了一些本地屬性浊闪,比如SDK的路徑恼布。

  • settings.gradle: 假如我們的項目包含了不只一個Module時,我們想要一次性構(gòu)建所有Module以完成整個項目的構(gòu)建搁宾,這時我們需要用到這個文件折汞。比如我們的項目包含了ModuleA和ModuleB這兩個模塊,則這個文件中會包含這樣的語句:include ':ModuleA', ':ModuleB'盖腿。

4. 構(gòu)建腳本

首先我們來看一下工程目錄下的build.gradle爽待,它指定了真?zhèn)€整個項目的構(gòu)建規(guī)則,它的內(nèi)容如下:

<pre style="margin: 0px; padding: 0px;">buildscript {
repositories {
jcenter() //構(gòu)建腳本中所依賴的庫都在jcenter倉庫下載
}
dependencies {
//指定了gradle插件的版本
classpath 'com.android.tools.build:gradle:1.5.0'
}
}

allprojects {
repositories {
//當(dāng)前項目所有模塊所依賴的庫都在jcenter倉庫下載
jcenter()
}
}</pre>

我們再來簡單介紹下app模塊的build.gradle的內(nèi)容:

<pre style="margin: 0px; padding: 0px;">//加載用于構(gòu)建Android項目的插件
apply plugin: 'com.android.application'

android { //構(gòu)建Android項目使用的配置
compileSdkVersion 23 //指定編譯項目時使用的SDK版本
buildToolsVersion "23.0.1" //指定構(gòu)建工具的版本

defaultConfig {
    applicationId "com.absfree.debugframwork" //包名
    minSdkVersion 15  //指定支持的最小SDK版本
    targetSdkVersion 23 //針對的目標(biāo)SDK版本
    versionCode 1 
    versionName "1.0"
}
buildTypes { //針對不同的構(gòu)建版本進(jìn)行一些設(shè)置
    release { //對release版本進(jìn)行的設(shè)置
        minifyEnabled false //是否開啟混淆
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  //指定混淆文件的位置
    }
}

}

dependencies { //指定當(dāng)前模塊的依賴
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
}</pre>

三翩腐、常見配置

整個工程的build.gradle通常不需我們改動鸟款,這里我們介紹下一些對模塊目錄下build.gradle文件的常見配置。

1. 依賴第三方庫

當(dāng)我們的項目中用到了了一些第三方庫時茂卦,我們就需要進(jìn)行一些配置何什,以保證能正確導(dǎo)入相關(guān)依賴。設(shè)置方法很簡單疙筹,比如我們在app模塊中中用到了Fresco富俄,只需要在build.gradle文件中的dependencies塊添加如下語句:

<pre style="margin: 0px; padding: 0px;">dependencies {
...
compile 'com.facebook.fresco:fresco:0.11.0'
}</pre>

這樣一來,Gradle會自動從jcenter倉庫下載我們所需的第三方庫并導(dǎo)入到項目中而咆。

2. 導(dǎo)入本地jar包

在使用第三方庫時霍比,除了像上面那樣從jcenter倉庫下載,我們還可以導(dǎo)入本地的jar包暴备。配置方法也很簡單悠瞬,只需要先把jar文件添加到app\libs目錄下,然后在相應(yīng)jar文件上單擊右鍵涯捻,選擇“Ad As Library”浅妆。然后在build.gradle的dependencies塊下添加如下語句:

<pre style="margin: 0px; padding: 0px;">compile files('libs/xxx.jar')</pre>

實(shí)際上我們可以看到,系統(tǒng)為我們創(chuàng)建的build.gradle中就已經(jīng)包含了如下語句:

<pre style="margin: 0px; padding: 0px;">compile fileTree(dir: 'libs', include: ['*.jar'])</pre>

這句話的意思是障癌,將libs目錄下的所有jar包都導(dǎo)入凌外。所以實(shí)際上我們只需要把jar包添加到libs目錄下并“Ad As Library"即可。

3. 依賴其它模塊

假設(shè)我們的項目包含了多個模塊涛浙,并且app模塊依賴other模塊康辑,那么我們只需app\build.gradle的denpendencies塊下添加如下語句:

<pre style="margin: 0px; padding: 0px;">compile project(':other')</pre>

4. 構(gòu)建輸出為aar文件

通常我們構(gòu)建的輸出目標(biāo)都是apk文件,但如果我們的當(dāng)前項目時Android Library轿亮,我們的目標(biāo)輸出就是aar文件疮薇。要想達(dá)到這個目的也很容易,只需要把build.gradle的第一句改為如下:

<pre style="margin: 0px; padding: 0px;">apply plugin:'com.android.library'</pre>

這話表示我們使用的插件不再是構(gòu)建Android應(yīng)用的插件我注,而是構(gòu)建Android Library的插件按咒,這個插件定義并執(zhí)行用于構(gòu)建Android Library的一系列Task。

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

只需進(jìn)行如下配置:

<pre style="margin: 0px; padding: 0px;">android {
...
}
buildTypes {
release {
...
shrinkResources true
...
}
}
}</pre>

6. 忽略Lint錯誤

在我們構(gòu)建Android項目的過程中但骨,有時候會由于Lint錯誤而終止励七。當(dāng)這些錯誤來自第三方庫中時智袭,我們往往想要忽略這些錯誤從而繼續(xù)構(gòu)建進(jìn)程。這時候呀伙,我們可以只需進(jìn)行如下配置:

<pre style="margin: 0px; padding: 0px;">android {
...
lintOptions {
abortOnError false
}
}</pre>

7. 集成簽名配置

在構(gòu)建release版本的Android項目時补履,每次都手動導(dǎo)入簽名文件,鍵入密碼剿另、keyalias等信息十分麻煩。通過將簽名配置集成到構(gòu)建腳本中贬蛙,我們就不必每次構(gòu)建發(fā)行版本時都手動設(shè)置了雨女。具體配置如下:

<pre style="margin: 0px; padding: 0px;">signingConfigs {
myConfig { //將"xx"替換為自己的簽名文件信息
storeFile file("xx.jks")
storePassword "xx"
keyAlias "xx"
keyPassword "xx"
}
}
android {
buildTypes {
release {
signingConfig signingConfigs.myConfig //在release塊中加入這行
...
}
}
...
}</pre>

真實(shí)開發(fā)中,我們不應(yīng)該把密碼等信息直接寫到build.gradle中阳准,更好的做法是放在gradle.properties中設(shè)置:

<pre style="margin: 0px; padding: 0px;">RELEASE_STOREFILE=xxx.jks
RELEASE_STORE_PASSWORD = xxx
RELEASE_KEY_ALIAS=xxx
RELEASE_KEY_PASSWORD=xxx</pre>

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

<pre style="margin: 0px; padding: 0px;">signingConfigs {
myConfig {
storeFilefile(RELEASE_STOREFILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}</pre>

關(guān)于Gradle的其他配置方法大家可以參考“延伸閱讀”部分的“Gradle最佳實(shí)踐”氛堕。

四、延伸閱讀

1.深入理解Android之Gradle

鄧凡平老師的一篇博文野蝇,從原理到使用非常深入細(xì)致地介紹了Gradle讼稚。而且重點(diǎn)介紹了怎樣把Gradle當(dāng)做一個編程框架來使用,介紹了Groovy語法基礎(chǔ)绕沈、Gradle常用API锐想,想要高度定制項目構(gòu)建過程的小伙伴們一定不要錯過這篇文章哦:)

2. Gradle構(gòu)建最佳實(shí)踐

這篇文章主要從使用者的角度介紹了Gradle在使用過程中的最佳實(shí)踐,同樣非常精彩乍狐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赠摇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子浅蚪,更是在濱河造成了極大的恐慌藕帜,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惜傲,死亡現(xiàn)場離奇詭異洽故,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)盗誊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門时甚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浊伙,你說我怎么就攤上這事撞秋。” “怎么了嚣鄙?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵吻贿,是天一觀的道長。 經(jīng)常有香客問我哑子,道長舅列,這世上最難降的妖魔是什么肌割? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮帐要,結(jié)果婚禮上把敞,老公的妹妹穿的比我還像新娘。我一直安慰自己榨惠,他們只是感情好奋早,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赠橙,像睡著了一般耽装。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上期揪,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天掉奄,我揣著相機(jī)與錄音,去河邊找鬼凤薛。 笑死姓建,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缤苫。 我是一名探鬼主播速兔,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼榨馁!你這毒婦竟也來了憨栽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤翼虫,失蹤者是張志新(化名)和其女友劉穎屑柔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體珍剑,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掸宛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了招拙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唧瘾。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖别凤,靈堂內(nèi)的尸體忽然破棺而出饰序,到底是詐尸還是另有隱情,我是刑警寧澤规哪,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布求豫,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蝠嘉。R本人自食惡果不足惜最疆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚤告。 院中可真熱鬧努酸,春花似錦、人聲如沸杜恰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽心褐。三九已至烙荷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間檬寂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工戳表, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桶至,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓匾旭,卻偏偏與公主長得像镣屹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子价涝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348