介紹
依賴關(guān)系管理是Gradle的閃光點(diǎn)。在這個(gè)腳本中最好的一點(diǎn),就是你所需要的只是添加一行到你的build.gradle中,然后Gradle就會從一個(gè)遠(yuǎn)程倉庫中下載與之相關(guān)的依賴關(guān)系的庫,以保證它的Classes對你的Project的是可用的。Gradle甚至解決了依賴項(xiàng)是自己的問題,這種依賴關(guān)系被稱之為Transitive Dependencies。
這一章會介紹以來管理并且解釋Android Project中添加依賴關(guān)系的幾種辦法。
Repositories
通常我們說的依賴,都是外部依賴,比如說提供給開發(fā)者的Libraries。手動管理依賴關(guān)系是一個(gè)很麻煩的事情,你必須定位Library,然后下載Jar文件,把它Copy到你的Project中,然后reference它。經(jīng)常這些Jar包在他們的名字上也看不到版本,所以還得在添加的時(shí)候記住版本號以便后續(xù)升級。你也需要保證Libraries保存在SCV中,用來保證團(tuán)隊(duì)成員能夠基于該Libraries而不用他們自己手動下載。
使用repositories可以解決這些問題。一個(gè)倉庫被認(rèn)為是很多文件的集合。Gradle不能為Project定義默認(rèn)的repositories,所以需要我們手動添加repositories代碼塊。如果使用了Android Studio的話,默認(rèn)就已經(jīng)完成這個(gè)操作了。代碼塊如下:
repositories {
jcenter()
}
Gradle支持三種不同的倉庫:
- Maven
- Ivy
- 靜態(tài)的文件或者目錄
所有的依賴文件都在構(gòu)建的執(zhí)行階段中,從這些倉庫中獲取。Gradle也會保存一個(gè)本地的緩存,所以一個(gè)指定的依賴Lib版本只會在機(jī)器上下載一次。
每一個(gè)依賴都會被三個(gè)部分唯一標(biāo)識,用這三個(gè)元素就可以在dependencies代碼塊中指定依賴的Lib了:
-
group:指定了該Lib的Organization,通常會是公司域名反過來,例如com.company.department -
name: 唯一標(biāo)示該Library -
version:標(biāo)識想用的哪個(gè)版本號
例如:com.google.code.gson是Library的group,gson是Library的name,2.3是Library的version
dependencies {
compile 'com.google.code.gson:gson:2.3'
compile 'com.squareup.retrofit:retrofit:1.9.0'
}
預(yù)配置的倉庫(Preconfigured repositories)
為了方便,Gradle已經(jīng)預(yù)配置了三個(gè)Maven倉庫:JCenter,Maven Central,Maven Local。通過下面的代碼塊即可引入
repositories {
mavenCentral()
jcenter()
mavenLocal()
}
Maven Central和JCenter是兩個(gè)著名的線上倉庫。沒必要同時(shí)時(shí)候,更加推薦使用JCenter,而Android Studio默認(rèn)就會配置該選項(xiàng)。JCenter是Maven Central的全集。
本地的Maven倉庫是一個(gè)所有使用過的依賴的本地緩存,我們也可以添加自己的依賴。默認(rèn)會在Home目錄下有一個(gè).m2的文件夾,在Linux或者M(jìn)ac上,路徑為~/.m2,而Windows上,路徑為%UserProfile%\.m2。
除了這些預(yù)置的倉庫外,我們也可以添加公共或者私密的倉庫
遠(yuǎn)程倉庫
一些組織創(chuàng)建了一些有趣的Plugin或者Libraries,并且把它們放到了他們自己的Maven或者Ivy服務(wù)器上,而沒有把它們公開在Maven Center或者JCenter中。為了添加這些依賴,我們所需要做的就是在maven代碼塊中添加URL。
repositories {
maven {
url "http://repo.acmecorp.com/maven2"
}
ivy {
url "http://repo.acmecorp.com/repo"
}
}
如果是私密的倉庫,我們可以加入credentials來訪問它。
repositories {
maven {
url "http://repo.acmecorp.com/maven2"
credentials {
username 'username'
password 'secretpassword'
}
} }
最好不要在這個(gè)代碼塊中寫入真正的賬號密碼,最好通過gradle.properties來保存,避免被人看到
本地倉庫
在本地硬盤或者網(wǎng)絡(luò)硬盤上可以構(gòu)建一個(gè)Maven或者Ivy的倉庫。通過添加以下配置,我們只需要配置一個(gè)URL到一個(gè)相對或者絕對路徑到硬盤即可:
repositories {
maven {
url "../repo"
}
}
一個(gè)新的Android Project會默認(rèn)依賴Android Support Library。當(dāng)通過SDK Manager安裝Google倉庫時(shí),兩個(gè)Maven倉庫就會在本地的硬盤中被創(chuàng)建:
ANDROID_SDK/extras/google/ m2repositoryANDROID_SDK/extras/android/m2repository
這也就是Gradle獲取Google Libraries的地方,比如說Android Support Librariy以及Google Play Services等。你可以添加一個(gè)常規(guī)的目錄作為倉庫,通過使用flatDirs,這也可以讓你從這個(gè)目錄下添加文件到依賴關(guān)系中:
repositories {
flatDir {
dirs 'aars'
}
}
本地依賴
有時(shí)候,我們?nèi)匀粫謩酉螺dJar包或者So等方式進(jìn)行依賴,接下來會介紹如何配置這些文件依賴,Native Libraries以及如何在Project中include library工程
文件依賴
添加Jar文件,我們可以使用Gradle提供的file和fileTree方法來添加單個(gè)或者整個(gè)文件目錄作為依賴,或者通過include來過濾其他的文件:
dependencies {
compile files('libs/domoarigato.jar')
compile fileTree('libs')
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Native Libraries
Android Plugin默認(rèn)支持Native Libraries,也就是.so文件,只需要我們創(chuàng)建一個(gè)目錄叫做jniLibs在Module級別目錄下,并且為每個(gè)平臺創(chuàng)建子目錄。把每個(gè)so放到對應(yīng)的目錄下。整個(gè)結(jié)構(gòu)如下:
app
├── AndroidManifest.xml
└── jniLibs
├── armeabi
│ └── nativelib.so
├── armeabi-v7a
│ └── nativelib.so
├── mips
│ └── nativelib.so
└── x86
└── nativelib.so
如果這種方式不起作用的話,我們可以在Module的build.gradle中指定它的位置:
android {
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
}
}
Library工程
如果希望創(chuàng)建一個(gè)共享的Library的話,和Application工程一樣,使用相同的Tasks來構(gòu)建Library工程,并且同樣可以構(gòu)建多種Library版本。不同的是,Application工程會生成出來一個(gè)APK,而Library會生成出來一個(gè)AAR文件。這個(gè)文件可以作為Project的Library引用。
創(chuàng)建并且使用Library工程
首先,在Module中不使用Android Application Plugin,而是使用Android Library Plugin:
apply plugin: 'com.android.library'
我們有兩種方法添加Library工程到Application中:
- 把Library工程作為Module加入Project
- 創(chuàng)建一個(gè)AAR文件,可以被多個(gè)Application的復(fù)用Lib
如果設(shè)置Library作為Module加入的話,可以在settings.gradle加入這個(gè)Module,并且把它加入到Application的依賴模塊中:
include ':app', ':libraryModule'
在這種情況下,libraryModule作為Library,并且把它添加到另外一個(gè)Module中作為依賴:
dependencies {
compile project(':library')
}
使用AAR文件
如果希望創(chuàng)建一個(gè)Library在各個(gè)Application中復(fù)用,則可以構(gòu)建出來一個(gè)AAR文件,并且作為依賴添加到Project中。AAR文件在assemble任務(wù)執(zhí)行后,會在build/output/aar/目錄下生成,只要Module構(gòu)建完成后,也都會生成。
想要添加AAR文件作為依賴,則需要在應(yīng)用的Module中創(chuàng)建一個(gè)目錄,然后把a(bǔ)ar文件放到該目錄中,然后把這個(gè)目錄作為repository添加到Module中:
repositories {
flatDir {
dirs 'aars'
}
}
上述方式會把文件夾中所有的文件都作為Dependency添加到依賴中,而如果只想添加單獨(dú)的AAR的話,可以通過下述方式,告訴Gradle,尋找名為libraryname,擴(kuò)展名為aar的文件:
dependencies {
compile(name:'libraryname', ext:'aar')
}
依賴關(guān)系的概念--Configuration
JCenter倉庫中的Version都會遵從一系列的規(guī)則,Version的格式為major.minor.patch,遵從以下規(guī)則:
-
major版本,當(dāng)有無法兼容的API版本時(shí),major版本會升級 -
minor版本,當(dāng)有向后兼容的功能添加時(shí)候,minor版本會升級 -
patch版本,當(dāng)修復(fù)了一些bug的時(shí)候,patch版本會升級
有些時(shí)候,可能使用SDK開發(fā)我們的功能,比如說藍(lán)牙SDK等,為了能夠編譯這些代碼,我們需要添加SDK到classpath中,但是不需要把SDK包含到APK中,因?yàn)檫@些SDK已經(jīng)在設(shè)備中存在了,這也就是依賴的Configuration中的作用了
Gradle的依賴配置有以下幾種:
- compile
- apk
- provided
- testCompile
- androidTestCompile
compile配置是默認(rèn)的配置項(xiàng),并且把所有的依賴項(xiàng)都編譯到Applicaion中。每一個(gè)配置都不僅僅會添加到classpath中,而是會被添加到APK中。
apk配置項(xiàng)僅僅會把依賴庫添加到包中,而不會把它添加到編譯的classpath中。provided配置項(xiàng)則與之相反,它的依賴項(xiàng)不會被添加到包中,而這兩種方式只能夠?qū)ar包的依賴生效,如果使用Library Project的話,會報(bào)錯(cuò)。
testCompile和androidTestCompile配置項(xiàng)會添加另外特殊的Library作為測試使用。這些配置項(xiàng)只會在執(zhí)行test相關(guān)的任務(wù)時(shí),才會使用,比如說使用JUnit或者Espresso的時(shí)候,會把相關(guān)的Framework添加進(jìn)去,并且只會在testApk中才會打包這些Framework,而不是在Release Apk中。
除了這些標(biāo)準(zhǔn)的配置項(xiàng)外,Android Plugin也會為每個(gè)構(gòu)建Variant添加一些配置項(xiàng),比如說debugCompile,releaseProvided等等。比如說當(dāng)只有Debug構(gòu)建時(shí)才要添加Log的Framework時(shí)會非常有用。
動態(tài)版本
在某些情況下,你可能需要每次都是用最新的依賴庫來構(gòu)建App或者Lib。最好的方法就是是用動態(tài)版本,以下為動態(tài)版本配置的示例:
dependencies {
compile 'com.android.support:support-v4:22.2.+'
compile 'com.android.support:appcompat-v7:22.2+'
compile 'com.android.support:recyclerview-v7:+'
}
第一行,我們告訴Gradle獲取最新的Patch版本。
第二行,我們告訴Gradle獲取最新的小版本
第三行,我們告訴Gradle獲取最新的版本