Gradle依賴那些事


先安利一個查詢項目依賴的命令:./gradlew 模塊名:dependencies

一、exclude

用法:exclude group:' ', module: ' ' 【 group和module兩個參數可分別單獨使用 】
說明:排除某個依賴,可解決部分傳遞依賴。

使用場景:

  • 解決依賴沖突。若兩個模塊使用相同 jar 包的不同版本,gradle 默認會使用最新版本的 jar 包,此時可以通過 exclude 排除沖突。(版本沖突帶來的問題最主要是API類或方法移除。)
  • 運行期無需此模塊。
  • 傳遞依賴無法找到時,可通過 exclude 排除。
  • 版權原因需排除。
compile 'com.android.support:support-v4:26.1.0'
    
    // 單獨排除某個模塊中的依賴  
    compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') {
        exclude group: 'com.android.support'
    }

    // 排除所有子依賴中的support依賴,統一使用主項目中的版本
    configurations {
       all*.exclude group: 'com.android.support'
    }

用法:主工程使用的 support 包版本為 26.1.0,使用 exclude group: 'com.android.support' 可以將 advrecyclerview 模塊中的 support 排除掉,統一使用主工程的 v26.1.0 版本。不管advrecyclerview依賴的該support包版本時高於還是低於主工程版本。

假設 advrecyclerview 中依賴的 support相關版本為 27.0.0,排除依賴前,項目依賴關系為:

project :shop
| + - com.android.support:appcompat-v7:26.1.0 ()
| + - com.android.support:support-v4:26.1.0 ()
| + - com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0
| | + - - - com.android.support:appcompat-v7:27.0.0 -> 26.1.0 ()
| | \ - - - com.android.support:recyclerview-v7:27.0.0 -> 26.1.0
| | + - - - - - com.android.support:support-annotations:26.1.0
| | + - - - - - com.android.support:support-compat:26.1.0 ()
| | \ - - - - - com.android.support:support-core-ui:26.1.0 (*)

對應的在build后,External Libraries 中會同時存在 support v27.0.0 和 v26.1.0 兩種版本的aar依賴。

排除 support 依賴后,External Libraries 就只會存在 v26.1.0 版本的aar。對應的依賴關系如下:

project :shop
| + - com.android.support:appcompat-v7:26.1.0 ()
| + - com.android.support:support-v4:26.1.0 ()
| + - com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0

二、transitive

用法:transitive = true | false

說明:是否傳遞本身的依賴給宿主程序(使用傳遞依賴時,Gradle 會將傳遞依賴一起下載下來。compile 默認是開啟傳遞依賴)

// 統一指定 transitive
configurations.all {
       transitive = false
}

// 單獨指定依賴項的 transitive 
compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') {
    transitive = false
}

transitive = true,依賴同於沒有使用 exclude 排除依賴 ,每個包的依賴項都會被遞歸分析並添加進來。
transitive = false,則依賴關系同於用 exclude 排除依賴。

Tips: exclude 和 transitive 可以同時使用,exclude會排除 transitive=true時的一些傳遞依賴。

三、force

用法:force = true
作用:強制使用某個版本。出現沖突時,優先使用該版本解決。

// 強制使用 support-v4 26.1.0版本
compile('com.android.support:support-v4:26.1.0') {
   force = true
}

四、動態版本(不建議使用)

使用場景:保持工程依賴都是最新版本。
使用方式:+,可以讓gradle每次構建時檢查遠程倉庫是否存在最新版本,若存在則下載。也可指定某個大版本下的最新子版本,1.+,表示始終依賴最新的 1.x 版本。

compile 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.+'

缺點:

  • 減低構建速度並且會提高構建失敗風險;
  • 新版本可能帶來兼容性問題。

五、綜合實例

compile('org.hibernate:hibernate:3.1') {
     // 沖突時優先使用該版本
     force = true

     // 依據構建名稱排除
     exclude module: 'cglib' 
     // 依據組織名稱排除
     exclude group: 'org.jmock' 
     // 依據組織名稱+構件名稱排除
     exclude group: 'org.unwanted', module: 'iAmBuggy' 

     // 為本依賴關閉依賴傳遞特性
     transitive = false
}

六、問題
1.項目中多個模塊依賴同一個依賴 D 的不同版本,如何保持每個模塊直接使用自己本身 compile 的依賴版本呢?
A:如果是直接 compile 包含不同版本的依賴,會造成依賴沖突。有一種方式可以直接將模塊打包成本地 jar 。打包成本地 aar 文件,也是不行,因為本地 aar 依賴,需要外部也 compile aar 中依賴的一些架包,否則會找不到。

另一種方式就很有效保證 各個模塊保持自己依賴的版本,而不用在意其他版本並且擔心產生沖突。具體如下:

configurations.all {
// 遍歷所有的依賴,根據 moduleName 使用對應的版本。確實可行
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
    def requested = details.requested
    if (requested.group == 'com.android.support') {
        if (requested.name.startsWith("multidex")) {
            details.useVersion '26.1.0'
        } else if (requested.name.startsWith("advrecyclerview")) {
            details.useVersion '27.0.0'
        } else {
            details.useVersion '25.3.0'
        }
    }
  }
}

七、本地aar依賴問題

場景:主工程app -> shop模塊 -> 依賴本地aar

問題:在主工程依賴 shop 模塊的遠程依賴時,無法找到依賴的本地 aar 相關。
解決:將 本地 aar 放到遠端,也是用遠程依賴。
原因:主要在於Android 3.0 后本地 aar 依賴無法越級傳遞依賴。可以看遠端 shop模塊 maven打包時生成的 .pom 文件,查看具體依賴,發現gradle 會把本地 aar 依賴也當做一份遠端依賴進行配置,但是沒有group等信息,如此在主工程中依賴 shop 模塊是,直接編譯不通過,因為會視為遠端倉庫的依賴,但實際並不存在。(根本原因未知)

問題:本地 jar 依賴和 本地 aar 依賴區別。

  • jar 文件只包含編譯好的 .class 文件和清單文件,不包含資源文件。所以如果沒有 res 資源文件,可以在打包時,將 packaging 配置為 jar 格式;
  • aar 文件包含 class 以及 /res 目錄下的所有資源文件。
    -查看 gradle 下載的遠程依賴區別就很明顯:
    image

本文轉自:https://www.jianshu.com/p/a38904a10988


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM