android - 将库添加到 Android 项目后出错(发现多个文件的操作系统独立路径 'META-INF/kotlinx-io.kotlin_module' )

标签 android android-studio gradle kotlin android-gradle-plugin

我一直在玩在 Android Studio 3.3(新空项目)中创建的“Hello World”项目,并决定 add a library (ktor)到项目。我按照 README 说明进行操作,并将所需的内容简单地添加到 gradle 文件中。当我使用 websockets 时,以下行已添加到应用程序的 gradle 构建文件中:

    implementation "io.ktor:ktor-client-websocket:$ktor_version"
    implementation "io.ktor:ktor-client-cio:$ktor_version"
    implementation "io.ktor:ktor-client-android:$ktor_version"
    implementation "io.ktor:ktor-client-cio:$ktor_version"

添加这些项目后立即停止编译,我收到以下错误:

More than one file was found with OS independent path 'META-INF/kotlinx-io.kotlin_module'

有人可以解释为什么我会收到此错误吗?我没有做任何违法的事情,我只是将库添加到在 Android Studio 中创建的简单、标准的空项目中,不知何故在添加新的依赖项后,一切都停止了。

我在 StackOverflow 和 GitHub Issues 上发现了一些类似的问题,但我没有找到很好的解释为什么会发生以及如何防止此类错误。我刚刚找到了一堆快速而简短的答案/解决方案,以“将其添加到您的项目配置中它会起作用,相信我,我是专家”的方式编写,但我对此并不满意,因为我认为作为一名开发人员,我必须了解我在做什么以及为什么它以这种方式工作,IMO 只是添加人们不完全理解的东西,希望它能解决问题是不专业的。

所以,我尽力去理解这个问题。据我基于其他答案的理解,这个问题是由于我不知何故在我的项目中有一个库的 2 个实例(?),所以 Gradle 无法理解选择哪个。但是后来我无法理解怎么办? (我没有添加任何其他“外部依赖项”)

至于解决方案,最常见的答案是将 'META-INF/kotlinx-io.kotlin_module' 添加到 excludePath 打包选项,但我没有不明白为什么它应该是正确的。对我来说,这听起来像是在告诉构建系统“请从我的项目中排除这些路径/不要扫描它们以查找库”。但我不确定这是否是一种正确的方法,因为在这种情况下,我有效地从我的项目中排除了几个库/依赖项,这可能会导致运行时异常 NoClassDefFoundError 或将来类似的东西。

第二个最常见的答案是将 pickFirst 'META-INF/kotlinx-io.kotlin_module' 添加到打包选项中,这看起来好一点,因为它告诉构建系统“当你有一些库的多个条目,请选择你找到的第一个”,即该库将包含在我的项目中,所以我是安全的,但我仍然担心这个解决方案作为一个来自C/C++/Rust/System_Programming 世界:就 C(简化版)而言,让我们想象一下,我最终拥有 2 个不同版本(1.1、1.2)的库,并且我有一个头文件,它期望我链接到 v.库的 1.2,如果我选择了一个错误的版本库 (1.1),但使用较新版本的 header 并期望它能正常工作,好吧......它显然不会工作,我认为可能会发生同样的问题在 Android 上(但我不确定,因为我不是专家),即 pickFirst 似乎是一个很好的解决方案,只要我们能保证我们正在使用的库的“多个条目”具有相同的版本。

所以我现在尝试使用 pickFirst 方法,结果在我的 gradle 构建文件中增加了一个部分:

    packagingOptions {
        pickFirst 'META-INF/kotlinx-io.kotlin_module'
        pickFirst 'META-INF/atomicfu.kotlin_module'
        pickFirst 'META-INF/kotlinx-coroutines-io.kotlin_module'
    }

哪个解决了这个问题,但我仍然不确定这是否是最佳解决方案。我认为正确的方法是了解错误发生的原因并解决错误的根本原因,而不是尝试使用其他打包选项来解决它。

最佳答案

Android 不需要 APK 包的 META-INF 目录中的任何这些文件。

META-INF 目录中的这些重复文件源自引用的库 -

除了使用 packagingOptions 之外别无他法。

另见:What is the purpose of META-INF? (Android APK != Java JAR)。

这些确实是类似的包格式,但还是不完全一样。

关于android - 将库添加到 Android 项目后出错(发现多个文件的操作系统独立路径 'META-INF/kotlinx-io.kotlin_module' ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54438064/

相关文章:

android - 如何在android studio中创建一个菱形按钮

spring - 如何获取 Spring Cloud Config 依赖项以从 Gradle 多模块构建中的父配置中解析?

android - Gradle DSL 方法未找到 : 'has()'

android - 如何为自定义 ExpandableListView 调用 notifyDataSetChanged?

android - 安全参数 : cannot resolve symbol 'string'

java - ViewPager内部 fragment 返回父 fragment 时不显示

android - 如何加速 Android Studio 3.0

android - 无法解析符号 'R' Android Studio 3.0

Android,检测其他应用程序何时启动,然后销毁该应用程序

Android Studio 和 Alfresco 移动 SDK