1. 程式人生 > >依賴引起錯誤

依賴引起錯誤

轉載 :https://blog.csdn.net/xx326664162/article/details/71488551

參考: 
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/animation/AnimatorCompatHe

Alpha support library version overriding previous support libs versions

All com.android.support libraries must use the exact same version specification

執行程式碼 loadMoreEnd()報錯

Android Support Repo 46.0.0 with Android Studio 2.3

Difference between compile and runtime configurations in Gradle

support中v4 v7庫版本錯誤,主要會報以下兩種錯誤,下面針對每一種錯誤進行詳解

第一種

錯誤資訊:

先來看兩個崩潰資訊,如下:

java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/animation/AnimatorCompatHelper;
  • 1
java.lang.NoSuchMethodError: No static method wrap(Ljava/lang/Object;)Landroid/support/v4/view/WindowInsetsCompat; in class Landroid/support/v4/view/WindowInsetsCompat; or its super classes (declaration of 'android.support.v4.view.WindowInsetsCompat' appears in /data/app/cn.xuexuan.newui-2/base.apk:classes12.dex)
  • 1
  • 2

經過這兩次錯誤的分析,總結出一個規律,凡是出現android/support/v4/中找不到類或者方法,可以確定是依賴了多個不同版本的support庫,都可以使用下面介紹的方法來解決。

分析:

以第一種錯誤為例,進行分析

log顯示,找不到v4庫下的這個類,但是我發現在support-v4-24.1.0中可以找到這個類,又想到在build.gradle中看到的這樣一個提示,

這裡寫圖片描述

我猜想,難道是在執行的時候,使用的不是support-v4-24.1.0的庫,使用了其他版本的庫???

原因:

經過一番查詢,和最後實踐證明,確實是使用了26.0.0-alpha1版本的庫(Support Repo 47.0.0 包括26.0.0-alpha1),在26.0.0-alpha1版本的庫中確實沒有AnimatorCompatHelper類。

因為某個模組的不同版本同時被依賴時,預設使用新版,gradle同步時不會報錯。所以這裡24.1.0版本的庫被自動替換為了26.0.0-alpha1版本的庫

要解決問題,就要找到哪個庫使用了26.0.0-alpha1,使用命令gradlew :app:dependencies檢視庫的依賴樹,發現compile ‘com.mcxiaoke.viewpagerindicator:library:2.4.1’使用了動態版本

這裡寫圖片描述

解決:

找到了原因,那麼解決起來就有頭緒了 
網上有人說,刪除掉compile ‘com.android.support:support-v4:+’,也算是一種方法吧。像上面這種依賴在第三方庫中,就需要下面的方法

第一種:

排除依賴中的指定包

compile ('com.mcxiaoke.viewpagerindicator:library:2.4.1') {
        exclude group: 'com.android.support'
    }
  • 1
  • 2
  • 3

第二種:

force強制設定某個模組的版本。

configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-v4:24.1.0'
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5

或者

com.android.support包名的庫版本都是用24.1.0

configurations.all {
   resolutionStrategy.eachDependency { DependencyResolveDetails details ->
       def requested = details.requested
       if (requested.group == 'com.android.support') {
           if (!requested.name.startsWith("multidex")) {
               details.useVersion '24.1.0'
           }
       }
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

第二種

錯誤資訊

gradle 4.+版本才會出現的錯誤

Android dependency 'com.android.support:support-compat' has different version for the compile (25.1.0) and runtime (25.3.0) classpath
  • 1

主要意思是在compile和runtime 時使用的support庫版本不一樣

分析

compile 是runtime 的一部分。 例如,假設一個名為app程式使用庫foo,而庫foo在內部使用庫bar。 編譯應用程式app只需要foo庫,但是執行app時需要foo和bar。 對Gradle compile的配置在其runtime 配置中也是可見的,但相反則不是這樣。

原因:

因為某個庫的不同版本同時被依賴時,預設使用較新版。

使用命令gradlew :app:dependencies檢視庫的依賴樹,

在compile 時,看不到庫mvp中依賴的support 版本,所以google play 相關的庫使用support-v4:24.0.0的版本。下面之所以看不到mvp庫中的依賴,是因為在引用第三方庫使用了implementation(gradle 4.+版本才出現的新特性。詳情可參考這裡

這裡寫圖片描述

在runtime時,運行了庫mvp中,其中依賴的support 版本為support-v4:25.1.0,

這裡寫圖片描述

所以google play 相關的庫使用support的較新版本25.1.0 
這裡寫圖片描述

導致出現了上面的報錯

解決

第一種:

解決方法和上面是一樣的

第二種:

在lib中使用api依賴第三方庫A,這樣在module中也可以使用庫A裡面的相關類

dependencies {
    api xxxxxx
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion '25.3.0'
            }
        }
    }
}