天天看點

【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

文章目錄

  • ​​一、查詢 Android 依賴庫的配置​​
  • ​​二、通過 ModuleDependency#transitive 依賴傳遞設定​​
  • ​​三、通過 ModuleDependency#exclude 設定排除子依賴庫​​
  • ​​四、通過 configuration 配置排除子依賴庫​​
  • ​​五、force 強制指定依賴庫​​

一、查詢 Android 依賴庫的配置

在遇到 依賴沖突 時 , 如果要 排查某個依賴的子庫 時 , 就需要對該依賴庫非常熟悉 , 最好是找出該依賴庫位置 , 并 分析該依賴庫的 Maven 配置檔案 , 即 pom.xml 配置檔案 ; 下面以 com.android.support:appcompat-v7 依賴庫 為例進行示範 , 這個庫經常會造成依賴沖突 ;

Android 官方提供的依賴庫 , 都放在 SDK 的 extras 目錄 下 , 如下圖所示 :

【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

其中 Android Support 依賴庫的路徑位置 , 在 D:\001_Develop\001_SDK\Sdk\extras\android\m2repository\com\android\support

【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

這裡以 appcompat-v7 依賴庫為例 , 檢視 23.3.0 版本的 com.android.support:appcompat-v7 依賴庫 , 其目錄為 D:\001_Develop\001_SDK\Sdk\extras\android\m2repository\com\android\support\appcompat-v7\23.3.0 , 依賴庫内容如下 :

【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

檢視其 appcompat-v7-23.3.0.pom 依賴配置檔案

<dependency>
      <groupId>com.android.support</groupId>
      <artifactId>support-v4</artifactId>
      <version>23.3.0</version>
      <type>aar</type>
      <scope>compile</scope>
    </dependency>      
【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

二、通過 ModuleDependency#transitive 依賴傳遞設定

在 dependencies 中配置依賴時 , implementation 依賴配置 後 , 可以 在閉包中 使用 transitive 函數 設定依賴是否傳遞 ,

  • 如果為 transitive 函數設定 true 參數 , 則 包含傳遞依賴 ;
  • 如果為 transitive 函數設定 false 參數 , 則 排除傳遞依賴 ;
dependencies {

    implementation ('androidx.appcompat:appcompat:1.4.1') {
        transitive true // 包括傳遞依賴, 如果設定為 false 則排除傳遞依賴
    }
}      

ModuleDependency#transitive 函數的原型如下 :

/**
     * 設定是否應解析此依賴項,包括或排除其可傳遞依賴項。
     * 屬于此依賴項的工件本身可能依賴于其他工件。
     * 後者稱為傳遞依賴。
     *
     * @param transitive 是否應解析可傳遞依賴項。
     * @return this
     */
    ModuleDependency setTransitive(boolean transitive);      

三、通過 ModuleDependency#exclude 設定排除子依賴庫

針對依賴庫沖突 : 依賴庫 A 中 , 包含了 B , C 分庫

  • 它們的 所有版本都是 1.0 版本
  • 應用突然 單獨的依賴了 2.0 版本的 B 依賴庫

這就 出現了沖突 , 此時就會 引入了兩個版本的 B 依賴庫 , 導緻了沖突 ;

在依賴庫中 , 可以将其中的某個依賴庫剔除 , 如 ​

​androidx.appcompat:appcompat​

​ 依賴庫中 , 依賴了

  • ​androidx.annotation:annotation​

    ​ 依賴庫
  • ​androidx.core:core​

    ​ 依賴庫
  • ​ndroidx.cursoradapter:cursoradapter​

    ​ 依賴庫
  • ​androidx.activity:activity​

    ​ 依賴庫
+--- androidx.appcompat:appcompat:1.4.1
|    +--- androidx.annotation:annotation:1.3.0
|    +--- androidx.core:core:1.7.0 (*)
|    +--- androidx.cursoradapter:cursoradapter:1.0.0
|    +--- androidx.activity:activity:1.2.4      

使用如下配置 , 在閉包中調用 ModuleDependency#exclude 方法 , 可以排除 ​

​androidx.activity:activity​

​ 依賴庫 ;

設定之後 , 導入 ​

​androidx.appcompat:appcompat​

​​ 依賴庫 , 就會将 ​

​androidx.activity:activity​

​ 依賴庫排除出去 , 不再加載該依賴庫 ;

dependencies {

    implementation ('androidx.appcompat:appcompat:1.4.1') {

        // 排除 androidx.annotation:annotation 依賴
        exclude group: "androidx.activity", module: "activity"
    }
}      

特别注意 : 如果在此處排除了 , 如果在其它地方引用了 ​

​androidx.appcompat:appcompat​

​ 依賴庫 , 則該設定無效 ;

ModuleDependency#exclude 方法函數原型如下 :

/**
 * 添加排除規則以排除此依賴項的可傳遞依賴項。
 * <p>
 * 排除特定的可傳遞依賴項并不保證它不會出現
 * 在給定配置的依賴性中。
 * 例如,沒有任何排除規則的某些其他依賴項,
 * 可能會引入完全相同的傳遞依賴關系。
 * 確定從整個配置中排除可傳遞依賴項
 * 請使用每個配置的排除規則:{@link configuration#getExcludeRules()}。
 * 事實上,在大多數情況下,配置每個依賴項排除的實際意圖
 * 實際上是從整個配置(或類路徑)中排除依賴項。
 * <p>
 * 如果您的意圖是排除特定的可傳遞依賴關系
 * 因為您不喜歡它引入配置的版本
 * 然後考慮使用強制版本的功能:{@link ResolutionStrategy#force(Object…)}。
 *
 * <pre class='autoTested'>
 * plugins {
 *     id 'java' // so that I can declare 'implementation' dependencies
 * }
 *
 * dependencies {
 *   implementation('org.hibernate:hibernate:3.1') {
 *     //excluding a particular transitive dependency:
 *     exclude module: 'cglib' //by artifact name
 *     exclude group: 'org.jmock' //by group
 *     exclude group: 'org.unwanted', module: 'iAmBuggy' //by both name and group
 *   }
 * }
 * </pre>
 *
 * @param excludeProperties 定義排除規則的屬性。
 * @return this
 */
ModuleDependency exclude(Map<String, String> excludeProperties);      

特别注意 : 如果在此處排除了 , 如果在其它地方引用了 ​

​androidx.appcompat:appcompat​

​ 依賴庫 , 則該設定無效 ;

四、通過 configuration 配置排除子依賴庫

首先 , 執行

gradlew app:dependencies --configuration releaseRuntimeClasspath      

指令 , 檢視 ​

​androidx.appcompat:appcompat​

​​ 依賴庫中 , 包含 ​

​androidx.activity:activity​

​ 依賴庫 , 如下圖所示 ;

【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

然後 , 在 configurations#configuration 腳本塊 中 , 配置如下依賴配置 :

configurations {
    configuration{
        all*.exclude group: "androidx.activity", module: "activity"
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1' 
}      

最後 , 再執行

gradlew app:dependencies --configuration releaseRuntimeClasspath      

指令 , 檢視 ​

​androidx.appcompat:appcompat​

​​ 依賴庫中 , 不再包含 ​

​androidx.activity:activity​

​ 依賴庫 ;

【Android Gradle 插件】Android 依賴管理 ⑥ ( 依賴沖突處理 | transitive 依賴傳遞設定 | exclude 依賴排除設定 | force 強制指定依賴庫 )

五、force 強制指定依賴庫

在 configurations.all#resolutionStrategy 腳本塊 中 , 可以 使用 force 強制指定依賴庫 ;

使用如下代碼 , 将 ​

​androidx.appcompat:appcompat​

​​ 依賴庫 , 強制指定為 1.2.0 版本 , 即使有更高版本的 ​

​androidx.appcompat:appcompat:1.4.​

​​ 依賴庫 , 也會強制使用該 ​

​androidx.appcompat:appcompat:1.2.0​

​ 低版本依賴庫 ;

configurations.all {
    resolutionStrategy {
        force 'androidx.appcompat:appcompat:1.2.0'
    }
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.4.1'
}      

執行

gradlew app:dependencies --configuration releaseRuntimeClasspath