【譯】Gradle 的依賴關係處理不當,可能致使你編譯異常

文章 | Ashesh Bharadwaj

翻譯 | 承香墨影html

受權 承香墨影 翻譯、編輯併發布android

在 Android Studio 中,Gradle 構建過程對於開發者來講,很大程度上是抽象的。做爲一個新的 Android 開發者,咱們第一次遇到 Gradle 一般是在 build.gradle 文件中添加一個遠程依賴項。程序員

讓咱們看看如何閱讀 Gradle 依賴關係樹,並解決與依賴關係有關的問題。shell

這是我工做中管理的一個項目,我想將 targetVersion 升級到 27,我也在 Gradle 中,更新了新版的 appcompat-v7 支持庫到最新的依賴版本 27.0.2。在更改以後,同步項目,在 build.gradle 中出現如下錯誤提示:api

該錯誤表示我必須使用徹底相同版本的支持庫。但是我只在個人 build.gradle 中,使用了這個支持庫。併發

Android Studio 的這個提示究竟是什麼意思?app

這個錯誤提示中,說起到的 com.android.support:animated-vector-drawable:27.0.2com.android.support-v4:21.0.3 是在哪裏又被引用了?post

若是隻是應用程序的直接依賴庫,只須要在 build.gradle 中指明依賴就行了,這樣很是的清晰明瞭。可是實際狀況並不是如此,這些依賴關係可能會進一步擁有本身的依賴關係,這被稱爲 依賴傳遞 。Gradle 須要在應用中包含全部的直接或者間接的依賴。學習

前面 Android Studio 提示的錯誤信息,正是咱們如今討論的這些傳遞性依賴關係致使的。gradle

Gradle 必須解決全部的這些依賴關係。包含使用了哪些庫?若是兩個不一樣的庫對同一個庫有不一樣版本的依賴關係,會發生什麼問題?

要查看 Gradle 依賴關係樹(Gradle 解析依賴關係的方式),咱們能夠到位於 Android Studio 底部的 Terminal 選項卡並輸入如下命令:

gradlew app:dependencies

這將顯示全部 構建變體 的依賴關係解析樹。咱們能夠在上面的命令中添加一個標識來查看特定構建變體的配置。例如 --configuration releaseCompileClasspath 將向咱們展現 release 變體的依賴樹。

關於構建變體,建議閱讀官方文檔:

https://developer.android.com...

以上是上述命令的輸出:

releaseCompileClasspath - Resolved configuration for compilation for variant: release
+--- com.android.databinding:library:1.3.1
|    +--- com.android.support:support-v4:21.0.3
|    |    \--- com.android.support:support-annotations:21.0.3 -> 27.0.2
|    \--- com.android.databinding:baseLibrary:2.3.0-dev -> 3.0.1
+--- com.android.databinding:baseLibrary:3.0.1
+--- com.android.databinding:adapters:1.3.1
|    +--- com.android.databinding:library:1.3 -> 1.3.1 (*)
|    \--- com.android.databinding:baseLibrary:2.3.0-dev -> 3.0.1
+--- com.android.support.constraint:constraint-layout:1.0.2
|    \--- com.android.support.constraint:constraint-layout-solver:1.0.2
\--- com.android.support:appcompat-v7:27.0.2
     +--- com.android.support:support-annotations:27.0.2
     +--- com.android.support:support-core-utils:27.0.2
     |    +--- com.android.support:support-annotations:27.0.2
     |    \--- com.android.support:support-compat:27.0.2
     |         +--- com.android.support:support-annotations:27.0.2
     |         \--- android.arch.lifecycle:runtime:1.0.3
     |              +--- android.arch.lifecycle:common:1.0.3
     |              \--- android.arch.core:common:1.0.0
     +--- com.android.support:support-fragment:27.0.2
     |    +--- com.android.support:support-compat:27.0.2 (*)
     |    +--- com.android.support:support-core-ui:27.0.2
     |    |    +--- com.android.support:support-annotations:27.0.2
     |    |    \--- com.android.support:support-compat:27.0.2 (*)
     |    +--- com.android.support:support-core-utils:27.0.2 (*)
     |    \--- com.android.support:support-annotations:27.0.2
     +--- com.android.support:support-vector-drawable:27.0.2
     |    +--- com.android.support:support-annotations:27.0.2
     |    \--- com.android.support:support-compat:27.0.2 (*)
     \--- com.android.support:animated-vector-drawable:27.0.2
          +--- com.android.support:support-vector-drawable:27.0.2 (*)
          \--- com.android.support:support-core-ui:27.0.2 (*)

在查找目的以前,理解 Gradle 依賴關係樹的格式很重要。

先來談談如下三個符號,它們的目的僅用於格式化:

  • +- - - 是依賴分支庫的開始。
  • | 標識仍是在以前的依賴庫中的依賴,顯示它依賴的庫。
  • \- - - 是依賴庫的末尾。

星號(*) 在依賴庫的末尾,意味着該庫的進一步依賴關係不會顯示,由於它們已經列在其餘某個子依賴樹中。

最重要的標識是 ->

若是 Gradle 發現多個依賴庫都依賴到同一個庫可是不一樣版本,那麼它必須作出選擇。畢竟包含同一個庫的不一樣版本是沒有意義的。在這種狀況下,Gradle 默認選擇該庫的最新版本。

例如:

| + — — com.android.support:support-v4:21.0.3
| | \ — — com.android.support:support-annotations:21.0.3 -> 27.0.2

在上面,Gradle 告訴說,在 support-v4:21.0.3 依賴關係樹中, support-annotations:21.0.3 依賴於更新的版本 support-annotations:27.0.2 ,因此 27.0.2 將被使用。

如今咱們知道如何閱讀 Gradle 依賴關係解析樹,咱們回到本文的核心問題:全部 com.android.support 庫必須使用徹底相同的版本

全部支持庫都屬於如下組 com.android.support。正如咱們在 Gradle 的依賴關係樹中看到的那樣,com.android.support:support-v4:21.0.3 是惟一具備版本 21.0.3 而且未解析到最新版本的支持庫 27.0.2,這就是形成衝突的緣由。

如何解決這個問題?有幾種方式,能夠作到這一點:

一、經過 ResolutionStrategy

經過 ResolutionStrategy 強制指定 Gradle 的版本。

android {
        configurations.all {
        // To resolve the conflict for com.android.databinding:library:1.3.1
        // dependency on support-v4:21.0.3        
        resolutionStrategy.force 'com.android.support:support-v4:27.0.2'
    }
}
關於 ResolutionStrategy 的具體細節,官方文檔中有詳細描述:

https://docs.gradle.org/curre...

二、在 build.gradle 中指明版本

要在 build.gradle 中,明確指定添加的是 com.android.support:support-v4:27.0.2。這將讓Gradle 覆蓋舊版本。

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    // To resolve the conflict for com.android.databinding:library:1.3.1
    // dependency on support-v4:21.0.3
    implementation 'com.android.support:support-v4:27.0.2'
    implementation 'com.android.support:appcompat-v7:27.0.2'
}

對我來講,在 build.gradle 中顯式添加依賴關係彷佛更加的天然,而且能夠留下注釋。當咱們再次更新庫來檢查它是否仍然須要顯式添加時,這個註釋將提醒我關注它。

一旦添加並進行項目同步以後,錯誤文本將消失。如今,若是咱們再次運行依賴關係命令,咱們將看到support-v4:21.0.3解決-> 27.0.2

大部分時候 Gradle 會正確解決依賴關係。而瞭解了 Gradle 的依賴關係,我想遇到這樣的問題咱們應該更清楚如何去解決它。

我但願這篇文章能讓咱們更進一步瞭解 Gradle 依賴關係樹和解決方案。

今天在公衆號後臺回覆成長『 成長』,將會獲得我整理的一些學習資料,也能回覆『 加羣』,一塊兒學習進步。

原文連接:
https://proandroiddev.com/and...

推薦閱讀:

相關文章
相關標籤/搜索