support v4/design/v7依赖的冲突的解决

简介: 屏幕快照 2018-01-25 上午11.27.27.png关键字:关键字:关键字:Suggestion: add 'tools:replace="android:value"' to element at AndroidManifest.
img_23badba0d69191f3db10b3b8f9d5a86a.png
屏幕快照 2018-01-25 上午11.27.27.png

关键字:关键字:关键字:Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:26:9-28:38 to override. 编译冲突 Merge 错误


1.前言

SDK 开发中通常会引用一些依赖,例如 SDK 中引用了 v4 和 v7 包,那么接入 SDK 的 APP 中也同样引用了 V4 V7 包,但是和 SDK 中的V4 V7 版本不一样,这种情况下会引发什么问题?

当工程中依赖的不同版本的同一个依赖库,重复依赖的库都是通过 gradle 网络依赖方式,那么 AS 会默认选择高版本。

但是如果既有本地依赖版本,又有网络依赖版本,结果就是引起重复依赖冲突。
解决方式:都走网络依赖

2.检查依赖报告

Terminal 终端面板里输入以下命令

// XXX表示想打印的module的name
gradle XXX:dependencies

依赖报告示例如下:

+--- project :libraryContentLink
|    \--- com.android.support:support-v4:25.1.0 -> 25.1.1
|         +--- com.android.support:support-compat:25.1.1
|         |    \--- com.android.support:support-annotations:25.1.1 -> 25.3.1
+--- com.lzy.widget:imagepicker:0.5.5
|    +--- com.android.support:appcompat-v7:25.1.1 (*)
|    +--- com.github.chrisbanes.photoview:library:1.2.4
|    |    \--- com.android.support:support-v4:22.0.0 -> 25.1.1 (*)
|    \--- com.android.support:recyclerview-v7:25.1.1 (*)

V4 和 V7 的顶级依赖是 -> 25.1.1
依赖报告中可以看到有些依赖标注了 *号,表示这个依赖被忽略了,这是因为其他顶级依赖中也依赖了这个传递的依赖, Gradle 会自动分析下载最合适的依赖。有些依赖形如22.2.1 ->23.1.1是由于默认会优先版本高的依赖.这个时候你想使用版本低的依赖的话需要排除掉高的依赖。因此这里需要排除Fresco里面的supportV4依赖。

3.两种情况的解决方案

Android Studio 机制:
Android Studio 默认情况下会优先高版本的依赖库。

实际情况分为两种
第一种情况:如果 SDK 中的版本高于 APP 中的版本?
解决方式一:
去掉 SDK 中的低版本依赖,使用 SDK 中的新版本(这个过程可以是 Android Studio自动完成,无需改动)

解决方式二:
如果 App 中不想引用高版本的 V4 V7 包,而 AS 中默认情况下会优先高版本的依赖库,这种情况下怎么办呢?需要手动处理排除依赖

compile('com.facebook.fresco:fresco:0.10.0') {
       exclude module: 'support-v4'
}

第二种情况:如果 SDK 中的版本小于 APP 中的版本?
很抱歉 APP 中的某些功能可能不正常。


4.验证方法数

https://github.com/KeepSafe/dexcount-gradle-plugin

验证不同的版本添加后对方法数的影响:

img_22a21ade62734e950be66312d5a5724e.png
1503140016991.png
img_259daf8cea6bd95262fadf65ee8cf997.png
1503140424945.png

简单的一个实现,验证了对方法数是没有影响的,在两个版本中

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)

26.0.0-alpha1以上版本中没有AnimatorCompatHelper类。

经过这两次错误的分析,总结出一个规律,凡是出现Android/support/v4/中找不到类或者方法,可以确定是依赖了多个不同版本的support库,都可以使用下面介绍的方法来解决。

强制设置某个模块的版本

force强制设置某个模块的版本。

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

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

dependencies {
  compile fileTree(include: ['*.jar'], dir: 'libs')
  ...
  configurations.all {
    resolutionStrategy.eachDependency { 
      DependencyResolveDetails details ->
        def requested = details.requested
          if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
              details.useVersion '25.1.0'
            }
          }
    }
  }
}

另外一种方式排除依赖中的指定包

compile ('com.mcxiaoke.viewpagerindicator:library:25.1.0') {
  exclude group: 'com.android.support'
}

描述:APP模块中添加v427.0.2解决

Error:Execution failed for task ':app:preDebugBuild'.
> Android dependency 'com.android.support:support-v4' has different version for the compile (22.0.0) and runtime (27.0.2) classpath. You should manually set the same version via DependencyResolution
img_903ccfc59d7cd1f15bc4557681c92573.png
1516675664556.png
Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller than version 16 declared in library[com.android.support:design:27.0.2]

产生原因:
某个依赖包的manifests中的minSdkVersion版本比项目的minSdkVersion要高
解决方法:
1.更改项目的uses-sdk:minSdkVersion
2.更改依赖包的uses-sdk:minSdkVersion
3.在项目的manifests标签下添加

设置minSdkVersion大于16


5.编译冲突场景

错误如下:


img_848fb94802c2e8abb6f79069d54bf56a.png
屏幕快照 2018-01-25 上午12.18.15.png
Error:Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute meta-data#android.support.VERSION@value value=(26.0.2) from [com.android.support:design:26.0.2] AndroidManifest.xml:28:13-35
    is also present at [com.android.support:support-v4:26.1.0] AndroidManifest.xml:28:13-35 value=(26.1.0).
    Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:26:9-28:38 to override.

发生编译错误的引来库配置如下:
app下下的build.gradle

android {
  compileSdkVersion 26
  defaultConfig {
    targetSdkVersion 26
  }
  ...
}
dependencies {
  ...
  implementation 'com.android.support:design:26.1.0'
}

module下的build.gradle

android {
  compileSdkVersion 26
  buildToolsVersion '26.0.2'
  ...
}
dependencies {
  ...
  implementation 'com.android.support:design:26.0.2'
}

6.编译冲突发生的原因

由于导入的SDK用的是design26.0.2的包,而当前项目里用的是design26.1.0Manifest文件合并失败。即项目内出现了不同的support或者其他库也引用了多个版本,合并出现了merge错误。


7.编译冲突如何解决

7.1 方法一:手动修改方式强制使用相同版本

降级App中的support版本
App中引用的design改为26.0.2SDK中的版本保持一致。往旧版本改,虽然问题可以解决,但是不推荐。


7.2 方法二:gradle配置方式强制使用相同版本

强制使用相同版本

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

7.3 方法3:升级App中的版本

module中引用如下

android {
  compileSdkVersion 26
  buildToolsVersion '26.0.2'
  ...
}
dependencies {
  ...
  implementation 'com.android.support:design:26.0.2'
}

app中的如下配置的时候引发了Merge错误。

android {
  compileSdkVersion 26
  defaultConfig {
    targetSdkVersion 26
  }
  ...
}
dependencies {
  ...
  implementation 'com.android.support:design:26.1.0'
}

当把app中的配置升级后

android {
  compileSdkVersion 27
  defaultConfig {
    targetSdkVersion 27
  }
  ...
}
dependencies {
  ...
  implementation 'com.android.support:design:27.0.2'
}

再次执行,发现问题解决了。上面提到了:项目内出现了不同的support或者其他库也引用了多个版本,合并出现merge错误。如果这个不同的support版本是跨大版本号的,例如moduel中用的是26.0.1app中用的是27.0.2,相差了一个level这时候会自动选择高版本的support,如果是26.0.226.1.0,相差的只是小版本,这时候可能需要手动处理了。


http://www.bubuko.com/infodetail-2027963.html
http://blog.csdn.net/p576518762/article/details/78320477
http://blog.csdn.net/xx326664162/article/details/71488551

目录
相关文章
|
Java API Android开发
Gradle 依赖关系中 compile和 implementation的区别
将在一个项目中展示implementation,api以及compile之间的差异。 假设我有一个包含三个Gradle模块的项目: • app(Android应用) • my-android-library(Android库) • my-java-library(Java库) app具有my-android-library与依赖。my-android-library具有my-java-library依赖。
590 0
Ant Design Pro: 请求接口函数复用
Ant Design Pro: 请求接口函数复用
Ant Design pro删除模块笔记(二)
Ant Design pro删除模块笔记(二)
89 0
Ant Design Pro:页面结构规范
Ant Design Pro:页面结构规范
116 0
|
前端开发 API
webpack配置篇(三十八):语义化版本(Semantic Versioning)规范格式
webpack配置篇(三十八):语义化版本(Semantic Versioning)规范格式
118 0
webpack配置篇(三十八):语义化版本(Semantic Versioning)规范格式
|
Java Maven
使用maven构建项目报错Cannot change version of project facet Dynamic Web Module to 3.0解决方案
使用maven构建项目报错Cannot change version of project facet Dynamic Web Module to 3.0解决方案
使用maven构建项目报错Cannot change version of project facet Dynamic Web Module to 3.0解决方案
|
缓存 Java API
Preference组件探究之Base,Support及AndroidX对比
Preference组件探究之Base,Support及AndroidX对比
Preference组件探究之Base,Support及AndroidX对比
|
资源调度 前端开发 JavaScript
|
iOS开发
ASO小知识:tweak去掉对rocketbootstrap的Depends依赖
ASO小知识:tweak去掉对rocketbootstrap的Depends依赖
520 0
ASO小知识:tweak去掉对rocketbootstrap的Depends依赖
|
API Android开发
技术干货 | 如何在 Library 中使用/依赖 mPaaS?
在使用 mPaaS 框架过程中,有时需要复用模块。复用时需要按照使用 Module 依赖的方式添加模块。
2370 0
技术干货 | 如何在 Library 中使用/依赖 mPaaS?