學(xué)習(xí)本系列前可以下載相關(guān)的github項(xiàng)目gradleLearnDemo。
地址:https://github.com/sososeen09/gradleLearnDemo
依賴(lài)管理是Gradle非常棒的一個(gè)功能,很多情況下,你只需要在構(gòu)建文件中添加一行代碼,Gradle就會(huì)從遠(yuǎn)程倉(cāng)庫(kù)中下載依賴(lài),在項(xiàng)目中就可以使用依賴(lài)中的類(lèi)。如果你所依賴(lài)的這個(gè)庫(kù)本身也有它自己的依賴(lài),Gradle會(huì)處理并解決這些問(wèn)題,這些依賴(lài)中的依賴(lài),被稱(chēng)作傳遞性依賴(lài)。
Gradle使用 dependencies 這個(gè)DSL來(lái)定義構(gòu)建所依賴(lài)的類(lèi)庫(kù),使用repositories 來(lái)告訴構(gòu)建從哪里獲取依賴(lài),當(dāng)你配置好后,Gradle會(huì)自動(dòng)下載依賴(lài),并存儲(chǔ)在本地緩存中,在構(gòu)建中使用它們,一個(gè)特定版本的依賴(lài)只會(huì)在你的機(jī)器上下載一次。
例如:
repositories {
mavenCentral()
}
dependencies {
compile 'org.jsoup:jsoup:1.9.2'
}
Gradle支持三種不同的依賴(lài)倉(cāng)庫(kù):Maven、Ivy和靜態(tài)文件或文件夾。一個(gè)依賴(lài)通常由三種元素定義的,可以稱(chēng)呼它們?yōu)橐蕾?lài)屬性。
- group:通常標(biāo)識(shí)一個(gè)組織、公司或者項(xiàng)目。如org.jsoup
- name:一個(gè)工件的名稱(chēng)唯一的描述了依賴(lài)。如::jsoup
- version:一個(gè)類(lèi)庫(kù)的版本號(hào)。如1.9.2
上面的dependencies,也可以使用map形式包含group、name、version屬性。例如:
dependencies {
compile group:'org.jsoup', name:'jsoup', version:'1.9.2'
}
對(duì)于依賴(lài)來(lái)說(shuō),唯一需要的字段是name。group和version都是可選的元素。盡管如此,為了表述清楚,建議添加group,而version可確保依賴(lài)庫(kù)不會(huì)自動(dòng)更新。
1 使用和配置倉(cāng)庫(kù)
為了方便,Gradle預(yù)定義了三個(gè)Maven倉(cāng)庫(kù):
- Jcenter
- Maven Central
- 本地Maven倉(cāng)庫(kù)
Gradle使用Maven Central倉(cāng)庫(kù)就是調(diào)用mavenCentral()方法,其它兩個(gè)倉(cāng)庫(kù)的使用也類(lèi)似。為了在構(gòu)建腳本中包含它們,你需要這么做:
repositories {
jcenter()
mavenCentral()
mavenLocal()
}
Maven Central 和JCenter是兩個(gè)有名的遠(yuǎn)程倉(cāng)庫(kù),一般不同時(shí)使用它們,通常推薦使用JCenter,它是Maven Central的超集,其也是Android Studio創(chuàng)建Android項(xiàng)目時(shí)的默認(rèn)依賴(lài)倉(cāng)庫(kù),而且JCenter還支持HTTPS。
本地Maven倉(cāng)庫(kù)是你已經(jīng)使用了的所有依賴(lài)的本地緩存,你也可以自己添加依賴(lài)。默認(rèn)情況下,依賴(lài)倉(cāng)庫(kù)可以在一個(gè)名為.m2目錄文件夾的主目錄中找到。在Linux或Mac OS X上,該路徑是~/.m2,在Windows上路徑是%UserProfile%/.m2。
除了這些預(yù)定義的依賴(lài)倉(cāng)庫(kù),你也可以添加其它的公有或私有倉(cāng)庫(kù),可以指定一個(gè)任意的Maven或者Ivy倉(cāng)庫(kù)的URL并且配置來(lái)使用身份驗(yàn)證,或者可以使用簡(jiǎn)單的文件系統(tǒng)倉(cāng)庫(kù)來(lái)解決依賴(lài)關(guān)系。
在項(xiàng)目中定義倉(cāng)庫(kù)的關(guān)鍵是RepositoryHandler接口,它提供了添加各種類(lèi)型倉(cāng)庫(kù)的方法。從項(xiàng)目上看,這些方法在repositories配置塊中被調(diào)用。
可以聲明多個(gè)倉(cāng)庫(kù),下載依賴(lài)的時(shí)候按照聲明的順序來(lái)檢查倉(cāng)庫(kù),倉(cāng)庫(kù)提供了依賴(lài)優(yōu)先原則,對(duì)于特定的依賴(lài)后續(xù)的倉(cāng)庫(kù)聲明不會(huì)被進(jìn)一步檢查。
repositories {
mavenLocal()
jcenter()
maven { url "https://jitpack.io" }
flatDir {
dirs 'libs'
}
}
Gradle API 支持兩種方式來(lái)配置一個(gè)自定義倉(cāng)庫(kù):maven()和mavenRepo()。
repositories {
maven {
name 'Custom Maven Repository'
url 'http://repo.acmp.com/release/'
}
}
也可以使用Ivy倉(cāng)庫(kù),
repositories {
ivy {
url 'http://repo.acmp.com/release/'
}
}
有些Maven倉(cāng)庫(kù)的訪問(wèn)需要憑證,那么可以這樣:
repositories {
maven {
url 'http://repo.acmp.com/release/'
credentials{
username 'user'
password 'secretPassword'
}
}
}
不建議在構(gòu)建配置文件中存儲(chǔ)憑證,最好是在本地一個(gè)單獨(dú)的未納入版本控制系統(tǒng)的屬性文件存儲(chǔ)憑證
扁平的目錄倉(cāng)庫(kù)
flat目錄是最簡(jiǎn)單和最基本的倉(cāng)庫(kù)形式。在文件系統(tǒng)中它是一個(gè)單獨(dú)的目錄,只包含jar文件或者Android 庫(kù)中的aar類(lèi)型的文件,沒(méi)有maven元數(shù)據(jù)。
當(dāng)聲明依賴(lài)時(shí),你只能使用name和versin屬性,不能使用group屬性,因?yàn)樗鼤?huì)導(dǎo)致產(chǎn)生不明確的依賴(lài)關(guān)系。
dependencies {
compile name: 'jsoup', version: '1.9.2'
}
repositories {
flatDir{
dirs 'flatlibs'
}
}
2 本地依賴(lài)
某些情況下,你可能仍然需要使用手動(dòng)下載的jar文件或原生庫(kù)。
你可以使用Gradle提供的files方法來(lái)添加jar文件作為一個(gè)依賴(lài),例如:
dependencies{
compile files('libs/jsoup.jar')
}
如果jar文件很多,我們一個(gè)一個(gè)的這樣依賴(lài)太繁瑣,就可以一次添加一個(gè)完成的文件夾:
dependencies{
compile fileTree('libs')
}
在Android Studio中創(chuàng)建Android項(xiàng)目的時(shí)候,新建的Android項(xiàng)目會(huì)有一個(gè)libs文件夾,其會(huì)被聲明為依賴(lài)的文件夾,并且通過(guò)過(guò)濾只依賴(lài)jar文件,而不是所有的文件:
dependencies{
compile fileTree(include: ['*.jar'], dir: 'libs')
}
原生依賴(lài)
如果想要使用C或C++編譯的原生依賴(lài)庫(kù).so文件,需要指明jniLibs的目錄。假設(shè).so文件也都放置在libs目錄下,如圖:

在腳本文件中就需要這么配置:
android {
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
依賴(lài)項(xiàng)目
如果在項(xiàng)目中創(chuàng)建了一個(gè)模塊作為依賴(lài)項(xiàng)目,那么需要在settings.gradle中添加該模塊,然后在應(yīng)用模塊中使用它作為依賴(lài)。比如,在Android項(xiàng)目中,app模塊是我們的主模塊,library模塊是依賴(lài)模塊,也稱(chēng)作依賴(lài)庫(kù)。
settings.gradle 中添加:
include ':app' ,' : library'
app模塊下的build.gradle中添加:
dependencies{
compile project(':library')
}
使用.aar文件
當(dāng)你已經(jīng)把a(bǔ)ar文件放置在libs目錄下或者其他的扁平文件目錄下,添加aar文件作為依賴(lài)可以這么操作:
compile(name: 'libraryname', ext: 'aar')
這樣就告知Gradle查找具有特定名稱(chēng)切擴(kuò)展名為.aar的依賴(lài)庫(kù)
3 依賴(lài)配置
前面我們講了添加依賴(lài)庫(kù)的時(shí)候,前面都要有一個(gè)compile。其實(shí)這個(gè)compile就是一個(gè)配置Configuration。
Gradle根據(jù)配置對(duì)依賴(lài)進(jìn)行分組,比如編譯Java時(shí)使用的是這組依賴(lài),運(yùn)行Java時(shí)又可以使用另一組依賴(lài)。每一組依賴(lài)稱(chēng)為一個(gè)Configuration,在聲明依賴(lài)時(shí),我們實(shí)際上是在設(shè)置不同的Configuration。
Java插件提供了6個(gè)現(xiàn)成的配置:compile、runtime、testCompile、testRuntime、archives、default。
而在Android中的插件也提供了幾個(gè)標(biāo)準(zhǔn)配置:compile、apk、provided、testCompile、androidTestCompile。
compile 是默認(rèn)的配置,在編譯主應(yīng)用時(shí)包含所有的依賴(lài),不禁會(huì)將依賴(lài)添加至類(lèi)路徑,還會(huì)生成對(duì)應(yīng)的apk。
如果依賴(lài)使用apk配置,則該依賴(lài)只會(huì)被打包到apk,而不會(huì)被添加到編譯類(lèi)路徑。
provided配置與apk配置相反,只在編譯的時(shí)候用到,其依賴(lài)不會(huì)被打包進(jìn)apk。
testCompile、androidTestCompile配置會(huì)添加用于測(cè)試的額外依賴(lài)庫(kù),在運(yùn)行測(cè)試相關(guān)的任務(wù)時(shí)會(huì)被用到。比如添加JUnit或者Espresso測(cè)試框架。
要自定義一個(gè)配置Configuration,我們可以這樣:
configurations {
myConfiguration {
description = 'this is my configuration'
visible = false
}
}
我們?cè)谧远x配置的時(shí)候,同時(shí)定義了該配置的一些屬性,description表示的是該配置的描述信息,visiable表示該配置是否可以在該P(yáng)roject之外可見(jiàn),默認(rèn)是true。還可以定義其它的屬性,具體可參考Configuration這個(gè)類(lèi)。當(dāng)然,你也可以什么都不寫(xiě)。configurations對(duì)應(yīng)的Gradle的Api中ConfigurationContainer
這個(gè)類(lèi)。
以上只是定義了一個(gè)名為myConfiguration的配置,我們并未向其中加入依賴(lài)??梢酝ㄟ^(guò)dependencies()方法向myConfiguration中加入實(shí)際的依賴(lài)項(xiàng):
dependencies {
myConfiguration 'org.jsoup:jsoup:1.9.2'
}
repositories {
mavenCentral()
}
運(yùn)行gradle dependencies 這個(gè)幫助task,會(huì)顯示當(dāng)前的依賴(lài)樹(shù)。此時(shí)可以看到我們?cè)趍yConfiguration這個(gè)配置中依賴(lài)的庫(kù):
myConfiguration - this is my configuration
\--- org.jsoup:jsoup:1.9.2
由于我們只依賴(lài)了一個(gè)庫(kù),所以依賴(lài)樹(shù)看著很簡(jiǎn)潔。如果依賴(lài)很多庫(kù),而這些依賴(lài)庫(kù)又都有傳遞性依賴(lài),就有可能發(fā)生依賴(lài)沖突。如果存在依賴(lài)沖突,在默認(rèn)情況下,Gradle會(huì)選擇最新版本,這和Maven是不同的,Maven會(huì)選擇離依賴(lài)樹(shù)最近的版本。如果你需要更改默認(rèn)的沖突解決策略,可以自行搜索相關(guān)內(nèi)容,本文就不多做介紹了。
使用Gradle API可以找到Gradle依賴(lài)的緩存文件放置的位置。
task printDependencies << {
configurations.getByName('myConfiguration').each { dependency ->
println dependency
}
}
執(zhí)行gradle printDependencies 命令,可以看到打印結(jié)果:
> Task :printDependencies
/Users/jason/.gradle/caches/modules-2/files-2.1/org.jsoup/jsoup/1.9.2/5e3bda828a80c7a21dfbe2308d1755759c2fd7b4/jsoup-1.9.2.jar
4 動(dòng)態(tài)版本聲明
如果想使用最新版本的依賴(lài),可以使用占位符 latest.integration 。例如 :
org.jsoup:jsoup:latest-integration
或者,聲明版本屬性,通過(guò)使用一個(gè)加號(hào)(+) 標(biāo)定它來(lái)動(dòng)態(tài)改變:
org.jsoup:jsoup:1.+
當(dāng)然了,我們最好是少用或者不用動(dòng)態(tài)版本聲明。
下一篇,我們開(kāi)始學(xué)習(xí)Gradle中的多項(xiàng)目構(gòu)建。