【问题标题】:Correct way to resolve error: all support libraries must use the exact same version解决错误的正确方法:所有支持库必须使用完全相同的版本
【发布时间】:2018-04-13 16:12:27
【问题描述】:

我正在使用 Tommy Buonomo 的优秀库(here on GitHub 和 this SO question where he introduced it)将位置指示器添加到 ViewPager,但是我收到关于支持库版本的 gradle 错误,这引发了更大的问题我。

具体错误是:

Error:(39, 20) All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 27.0.0, 25.3.1. Examples include 'com.android.support:support-compat:27.0.0' and 'com.android.support:animated-vector-drawable:25.3.1'

(请注意,Android Studio 将其标记为 Error,但应用仍可编译并运行。)

这引发的更大问题是如何正确处理此类支持库版本中的冲突?

我已经添加了库,只需添加:

compile 'com.tbuonomo.andrui:viewpagerdotsindicator:1.0.1'

到我的应用程序级别 build.gradle 中的依赖项,正如我所说的,除了错误之外一切都运行良好。

我想让我的应用尽可能避免错误和警告,因此我想了解我可以做些什么来解决这个问题。

这是我第一次在我的一个项目中使用第三方库,所以这是我第一次遇到这个特定问题。

所以,一些问题。

  1. 库开发人员必须创建针对特定其他支持库版本的库的各种版本,还是他们可以简单地创建一个支持所有版本的库,直到特定版本? (必须创建特定版本似乎不切实际,因为您不知道库用户将使用哪些版本)。

  2. 用户通常可以更改第三方库调用的其他支持库的版本吗?我似乎在项目树的外部库部分中找不到任何可以让我为 Tommy 的库执行此操作的地方,所以我假设许多库都是这样的。

  3. 只有等待库开发人员创建一个使用与我的应用程序使用的相同 API 级别支持库的新版本的选项吗? (或者更改我的应用使用的支持库版本)。

  4. 另一种选择是在 github 上 fork 库并更改它在新 fork 中使用的支持库版本吗?这引发了学习如何编译和使用库并重新发布它们以供其他人使用的问题(可能作为对原始作者的拉取请求,以便他们可以合并更改 - 这将最符合 Tommy 发布的精神无论如何图书馆) - 并且还需要理解所有问题 1-3。

我觉得遇到了这个错误,我在这里打开了一罐蠕虫,但我想了解更多关于这个应该如何解决的问题。

(仅供参考,我正在使用编译和目标 SDK v27 构建我的应用程序,以遵循针对最新 API 级别的最佳实践。Tommy 的库已经有一个拉取请求以支持 API v26,该请求正在等待操作)

【问题讨论】:

  • 这些库中的大多数指向库所有者构建的 aar 或 jar。所以他需要更新他的构建版本并构建新的库。
  • 您使用的是什么版本的支持库?

标签: android android-studio android-gradle-plugin


【解决方案1】:

你可以强制依赖使用特定版本的support library,尝试在你的项目级build.gradle文件中添加这个:

subprojects {
    project.configurations.all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex') ) {
                details.useVersion "yourSupportLibVersion"
            }
        }
    }
}

如果您使用的是支持库版本 27.0.0,请将 yourSupportLibVersion 替换为 27.0.0

说明:

  • 我们为什么要使用子项目?

    在多项目 gradle 构建中,您有一个根项目和子项目。根项目是构建的起点。其他所有内容,无论是作为依赖项添加到 gradle 中还是手动添加的外部库,都将被 gradle 作为子项目处理。

  • 什么是解决策略?

    引用docs,ResolutionStrategy 定义了围绕依赖关系解析的策略。例如,强制某些依赖版本、替换、冲突解决或快照超时。

  • 为什么要排除multidex?

    我们之所以将multidex 排除在强制要求的版本之外,是因为multidex 的依赖名称还包含com.android.support,即com.android.support:multidex:someVersion,其中someVersion 不一样作为支持库版本,它独立于它,这就是我们将其排除在强制支持库版本之外的原因。 注意:如果你有更多这样的依赖,你应该在上面的if条件中添加它们。

在我们确保依赖确实是一个支持库之后,我们只是告诉 gradle 使用我们想要的版本。

【讨论】:

  • 嗯,这似乎有效,将其添加到我的 build.gradle 的末尾并没有破坏任何东西(我如何确认我编辑的文件是“根”build.gradle?)但是,AS 编辑器仍然显示错误,当我执行 git commit 时,它会识别该错误。
  • 我的意思是项目*级别build.gradle
  • 所以这与依赖项下的compile 指令位于同一个文件中?文件中的位置重要吗?添加后,编辑器(和 git)中的错误(红色下划线)是否应该消失?
  • 好的,已经移动了,编辑器中的错误已经消失,但现在我收到如下构建时错误:Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. > com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex。
  • 完美? - 构建没有错误,编辑器没有错误。修复速度比我预期的要快,应用程序似乎运行良好 - 现在只需要再次跨 API 版本进行测试。
【解决方案2】:

您提到的库正在使用 appcompat 库的v25.3.1,并且最近 4 个月没有更新。

为避免支持库版本冲突,我认为您应该克隆/下载该库并将其作为模块依赖项手动包含在您的项目中,以便您可以更新 appcompat 库的版本并毫无问题地使用它。

  • 将 git 存储库克隆到另一个目录。
  • 在Android Studio中选择File → Import Module and choose the module directory(包含build.gradle文件的那个)
  • 然后右击你的模块app → open module settings → dependencies → add module dependency

【讨论】:

  • 我喜欢这种方法的声音,因为它让我对我的源代码有了更多的控制。您能否详细说明一下我需要将下载放在哪里(在我的项目下或为其创建一个新项目?),然后我如何使其可用于我的项目? (通过 compile 指令添加为库让事情变得如此简单!)
  • @FatMonk 虽然当您想要自定义库或只有一个外部库时这是一个很好的解决方案,但我相信克隆每个外部库不是一个好主意如果您有很多(比如 5 个)库,并且每个库都使用不同版本的支持库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-23
相关资源
最近更新 更多