依賴-管理依賴的版本(傳遞(transitive)\排除(exclude)\強制(force)\動態版本(+))
我主要使用了exclude,使用exculde去除重複的依賴,比如 引入的多個第三方包都包含 okhttp 就可以使用該方法去除:
A: compile ‘com.test.aaa’
B : compile 'com.test.bbb'
C: compile 'com.test.ccc'
D: compile 'com.squarequ.okhttp3'
例如 自己的專案中依賴了 okhttp 還依賴了A B C 三個第三方包,A B C 中都依賴了 okhttp ,直接編譯 不能通過 報錯
Error:Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Lokhttp3/Address;
這樣 就要去除 A B C 中的okhttp ,使用方法
compile ('com.test.aaa'){
exclude group'com.squarequ.okhttp3'
}
這樣就去掉了A 依賴中的okhttp . B C 同理。
什麼是傳遞依賴
在Maven倉庫中,構件通過POM(一種XML檔案)來描述相關資訊以及傳遞性依賴。Gradle 可以通過分析該檔案獲取獲取所以依賴以及依賴的依賴和依賴的依賴的依賴,為了更加直觀的表述,可以通過下面的輸出結果瞭解。
+--- org.springframework:spring-web:4.3.4.RELEASE
| | +--- org.springframework:spring-aop:4.3.4.RELEASE
| | +--- org.springframework:spring-beans:4.3.4.RELEASE
| | +--- org.springframework:spring-context:4.3.4.RELEASE
| | \--- org.springframework:spring-core:4.3.4.RELEASE
可以看到,我們的專案依賴了spring-web
spirng-web
卻依賴了一眾spring的全家桶,藉助Gradle的傳遞性依賴特性,你無需再你的指令碼中把這些依賴都宣告一遍,你只需要簡單的一行,Gradle便會幫你將傳遞性依賴一起下載下來。
compile `org.springframework:spring-web:4.3.4.RELEASE`
- 1
傳遞依賴特性可以輕鬆地通過transitive引數進行開啟或關閉,上面的示例中如果要忽略spring-web
的傳遞性依賴可以採用指定 transitive = false
的方式來關閉依賴傳遞特性,也可以採用新增@jar
的方式忽略該依賴的所有傳遞性依賴。
compile("org.springframework:spring-web:4.3.4.RELEASE") {
transitive = false
compile `org.springframework:spring-web:[email protected]`
- 1
下面的語句,可以全域性性的關閉依賴傳遞特性。
configurations.all {
transitive = false
}
排除依賴
有些時候你可能需要排除一些傳遞性依賴中的某個模組,此時便不能靠單純的關閉依賴傳遞特性來解決了。這時exclude
就該登場了,如果說@jar
徹底的解決了傳遞問題,那麼exclude
則是部分解決了傳遞問題。然而實際上exclude
肯能還會用的頻率更更頻繁一些,比如下面幾種情況。
- 依賴衝突時,如果有兩個依賴引用了相同jar包的不同版本時,預設情況下gradle會採用最新版本的jar包,此時可以通過排除選項來排除。
- 執行期無需此模組的。
- 無法正常獲取到此傳遞依賴,遠端倉庫都不存在的。
- 版權原因需要排除的。
- 其他原因。
可以通過configuration配置或者在依賴宣告時新增exclude
的方式來排除指定的引用。
exclude可以接收group和module兩個引數,這兩個引數可以單獨使用也可以搭配使用,其中module可以理解為對應GAV中的artifactId,也就是compile group: 'org.gradle.test.classifiers', name: 'service', version: '1.0'
中的中間name部分。
configurations {
//編譯期排除commons模組
compile.exclude module: 'commons'
//在整個構建過程中排除pkaq.tiger:share
all*.exclude group: 'pkaq.tiger', module: 'share'
}
dependencies {
compile("pkaq.tiger:web:1.0") {
exclude module: 'share'
}
}
使用強制版本
當然,有時候你可能僅僅是需要強制使用某個統一的依賴版本,而不是排除他們,那麼此時force
就該登場了。指定force = true
屬性可以衝突時優先使用該版本進行解決。
compile('org.hibernate:hibernate:3.1') {
force = true
}
全域性配置強制使用某個版本的依賴來解決依賴衝突中出現的依賴
configurations.all {
resolutionStrategy.force('com.aliyun.iot.component.base:ilop-component:0.0.5')
}
使用動態版本
如果你想讓你的工程始終採用最新依賴,那麼Gradle提供了一種方式可以始終保證採用依賴的最新版本而無需每次手工檢查修改版本。
使用加號+
,可以讓Gradle在每次執行構建時檢查遠端倉庫是否存在該依賴的新版本,如果存在新版本則下載選用最新版本。當然也可以指定依賴某個大版本下的最新子版本,1.+
表示始終採用該依賴最新的1.x
版本的最新依賴。
compile 'org.springframework:spring-web:+'
- 1
雖然這是看上去十分風騷的一種用法,但這無疑會降低你係統構建的速度同時提高構建失敗的風險。因為Gradle不得不每次檢查遠端倉庫是否存在最新版本,同時新版本也可能帶來無法預知的相容性問題,比如
quartz2.x
較之於quartz1.x
,common-lang3
較之於common-lang
等。
一個綜合示例
compile('org.hibernate:hibernate:3.1') {
// 衝突時優先使用該版本
force = true
// 依據構建名稱排除
exclude module: 'cglib'
// 依據組織名稱排除
exclude group: 'org.jmock'
// 依據組織名稱+構件名稱排除
exclude group: 'org.unwanted', module: 'iAmBuggy'
// 為本依賴關閉依賴傳遞特性
transitive = false
}