【问题标题】:Android Library project com.android.dex.DexException: Multiple dex files define Lcom/google/gson/JsonSerializerAndroid Library项目com.android.dex.DexException:多个dex文件定义Lcom/google/gson/JsonSerializer
【发布时间】:2016-08-10 13:37:56
【问题描述】:

我正在 Android Studio 中编写一个库项目。我的 gradle 文件包括 gson volley play-services 等...
将我的库嵌入到项目中时,我得到:

com.android.dex.DexException:多个dex文件定义了Lcom/google/gson/JsonSerializer;

有人能解释一下在创建库项目时 gradle 是如何工作的吗?
我应该向集成我的 SDK 的开发人员解释什么,排除模块是如何工作的,以及为什么它在包含我的 aar 的应用中不起作用?

【问题讨论】:

  • 检查你的 lib 项目有播放服务/没有
  • 您的应用程序的依赖项中似乎有不同版本的 gson 库。
  • 我是编译库项目的人,它需要goog play服务。
  • 我的问题是,当我将编译好的 aar 放入 gradle 文件中带有 gson 的项目中时,我收到了该消息。我的印象是 gradle 应该解决冲突

标签: android dependencies android-gradle-plugin aar


【解决方案1】:

有两种情况需要考虑

  • 首先,如果您在 app/build.gradle 中声明了 Gson,请考虑删除它

    依赖{ 编译'com.google.code.gson:gson:2.4' }

  • 其次,如果您还没有在app/build.gradle 中声明它 您可能需要调查哪些库有重复声明 Gson 依赖。然后您可以从该库中排除 Gson。 你可能想检查这个Excluding transitive dependencies

在这里,我将提供一个从库中排除 appcompat-v7 的示例

运行此命令查看依赖关系图树

./gradlew app:dependencies

它将像下面的示例一样显示依赖关系树

|    \--- com.mikepenz:materialdrawer:4.6.3
|         +--- com.android.support:appcompat-v7:23.1.1 (*)
|         +--- com.android.support:recyclerview-v7:23.1.1 (*)
|         +--- com.mikepenz:materialize:0.5.1
|         |    \--- com.android.support:appcompat-v7:23.1.1 (*)
|         +--- com.mikepenz:iconics-core:2.5.3
|         |    \--- com.android.support:appcompat-v7:23.1.1 (*)
|         \--- com.android.support:support-annotations:23.1.1

在你发现库声明重复依赖之后。你可以开始排除它了。

dependencies {
    compile("com.mikepenz:materialdrawer:4.6.3") {
        exclude module: 'appcompat-v7'
    }
}

【讨论】:

  • 你能详细说明“排除模块”吗?,我没有应用程序项目。如果他们想使用另一个版本的 gson,我需要告诉集成了我的 sdk 的应用程序开发人员放入 build gradle 吗? @thann
  • 在您的情况下,您的 Gson 有问题。所以,我认为你应该通知他们排除它。编译('your_sdk_dependency'){排除组:'com.google.code.gson',模块:'gson'}
  • 或者,如果你的 sdk 项目在 maven 或 jcenter 中不可用,你可以试试这个。 compile(project(':you_sdk')) { 排除组:'com.google.code.gson',模块:'gson' }
  • 你解决了我 1 周的调试和搜索问题!谢谢!
【解决方案2】:

如果您无法选择删除 GSON,请尝试在您的 build.gradle 文件中启用多索引支持:

android {
   ...
   ...
         defaultConfig {
             ...
             ...
             // Enabling multidex support.
             multiDexEnabled true
         }
}

【讨论】:

    【解决方案3】:

    Gradle 无法神奇地解决这个问题 - 您的 SDK 和用户的应用程序中可能存在同一个库的不同版本 - 它们无法合并或以某种方式区分。

    我还开发了使用几个流行的第三方库的 SDK。我刚刚声明我使用了它们,并且如果用户也需要它们,则不必在他自己的应用程序中为这些依赖项提供 jar。我认为只要您在 SDK 中提供这些库的最新版本就可以了。

    1. 我能想到的避免冲突的唯一好方法是更改​​导入库中的类名 - 但这真的很枯燥乏味。您也可以使用gradle shadow plugin 之类的东西来重新定位包裹,但这对我来说似乎有风险。它看起来像这样:

    shadowJar { relocate 'com.google.gson', 'shadow.com.google.gson' }

    1. 您的开发人员也可以解压缩您的库,删除 gson 并将其重新 jar。但是,如果他使用其他版本的 gson,您的库可能会损坏。

    2. 哦,是的,您还可以将 SDK 作为源代码分发,而不是作为 JAR - 然后用户将能够将其添加到他们的应用程序中并使用他们想要的任何库。但通常你不想将你的 SDK 代码公开(即使通过库 jar 很容易反转......)。

    【讨论】:

    • 首先谢谢,我不明白,如果我在我的库项目中使用 gson,我不能告诉主机应用程序不要使用 gson,这太疯狂了。这是一种奇怪的行为,我正在寻找一个不适合我的 gradle 解决方案,例如 exclude。
    • 您可以告诉主机应用程序开发人员使用您的内置 gson 版本。他将无法包含他自己的 gson 库,但他将能够使用包含在您的库中的 gson 版本。至于魔术排除解决方案——如果你设法从你的库中排除 gson(是的,这是可能的)——那么它将停止工作,除非用户将完全相同的 gson 版本添加到他的应用程序中。
    【解决方案4】:

    dx 的 --multi-dex 选项与预 dexing 库项目不兼容。因此,如果您的应用使用库项目,则需要先禁用 pre-dexing,然后才能使用 --multi-dex。

    更新你的 IDE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-22
      • 2018-07-01
      • 2018-01-15
      • 2017-08-14
      相关资源
      最近更新 更多