1. 程式人生 > >support中v4 v7庫版本錯誤詳解

support中v4 v7庫版本錯誤詳解

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

第一種

錯誤資訊:

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

java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/animation/AnimatorCompatHelper;
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)

經過這兩次錯誤的分析,總結出一個規律,凡是出現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'
    }

第二種:

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

configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-v4:24.1.0'
    }
}

或者

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'
           }
       }
   }
}

第二種

錯誤資訊

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

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

主要意思是在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
}