如何解决java.util.zip.ZipException错误?

51
无论我尝试调试和部署我的Android应用程序(在Android Studio 0.9中),都会出现以下错误:

Execution failed for task ':app:packageAllDebugClassesForMultiDex'.
java.util.zip.ZipException: duplicate entry: android/support/multidex/BuildConfig.class

为了澄清事情,这里是我的行动简史:

  1. 今天早上项目正常运行
  2. 添加了一些附加类和方法
  3. 超过了限制并收到了以下错误:Unable to execute dex: method ID not in [0, 0xffff]: 65536
  4. 决定为项目添加multiDex支持,因为减少依赖项不是一个选项

自那以后,按照这篇Stack Overflow帖子(使用Gradle将外部库拆分为单独的dex文件以解决Android Dalvik 64k方法限制)添加multiDex到我的项目后,我一直收到描述的错误。

下面是我的build.gradle文件:

apply plugin: 'com.android.application'

repositories {
    jcenter()
}

android {
    compileSdkVersion 21
    buildToolsVersion '21.1.0'

    defaultConfig {
        applicationId "com.stackoverflow.application"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
        multiDexEnabled = true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    dexOptions {
        preDexLibraries = false
    }
}

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        dx.additionalParameters += '--multi-dex'
        dx.additionalParameters += "--main-dex-list=$projectDir/<filename>".toString() // enable the main-dex-list
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':viewPagerIndicatorLibrary')
    compile 'com.google.android:multidex:0.1'
    compile 'com.j256.ormlite:ormlite-android:4.48'
    compile 'com.j256.ormlite:ormlite-core:4.48'
    compile 'de.greenrobot:eventbus:2.2.1'
    compile 'se.emilsjolander:stickylistheaders:2.5.1'
    compile 'joda-time:joda-time:2.5'
    compile 'com.makeramen:roundedimageview:1.4.0'
    compile 'javax.inject:javax.inject:1'
    compile 'com.squareup.picasso:picasso:2.3.4'
    compile 'com.googlecode.libphonenumber:libphonenumber:6.3.1'
    compile('com.google.api-client:google-api-client-gson:1.18.0-rc') {
        exclude module: 'httpclient'
    }

    compile 'com.google.android.gms:play-services:6.1.71'
    compile('com.google.api-client:google-api-client:1.17.0-rc') {
        exclude(group: 'xpp3', module: 'xpp3')
        exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
        exclude(group: 'junit', module: 'junit')
        exclude(group: 'com.google.android', module: 'android')
    }
    compile('com.google.api-client:google-api-client-android:1.17.0-rc') {
        exclude(group: 'com.google.android.google-play-services', module: 'google-play-services')
    }
    compile('com.google.http-client:google-http-client-android:1.17.0-rc') {
        exclude(group: 'com.google.android', module: 'android')
    }
    compile 'com.google.guava:guava:18.0'
}

我还有另一个项目依赖于 viewPagerIndicator 库,以及我的 /libs 文件夹中的一些 jars:

  • android-async-http-1.4.6.jar
  • guice-3.0-no_aop.jar
  • jsr305-1.3.9.jar
  • roboguice-2.0.jar

如果您有任何关于如何解决这个问题的建议而不必移除我所需的任何依赖项,请不吝赐教!

11个回答

32

这个帖子发表有一段时间了,但是我也遇到了同样的错误。

我的问题是在 gradle 文件中使用了两个不同版本的 com.google.android.gms:play-services 库。

compile 'com.google.android.gms:play-services-gcm:7.5.0'
compile 'com.google.android.gms:play-services-analytics:7.3.0' // WRONG!

请确保您始终使用相同的版本,例如:

compile 'com.google.android.gms:play-services-gcm:7.5.0'
compile 'com.google.android.gms:play-services-analytics:7.5.0'

我也遇到了类似的问题...谢谢Dennis - SAIR

14

编辑:这是一个漏洞,已经有修复计划。请参见https://code.google.com/p/android/issues/detail?id=81804

我也遇到了这个问题,但我没有答案。以下是我可以提供的信息:

BuildConfig类是构建过程中生成的一个神奇的类。由于某种原因,在mutildex-1.0.0multidex-instrumentation-1.0.0的aar包中,存在同名的完全限定名称版本(android.support.multidex.BuildConfig)。

我不认为我们做错了什么。我认为这是处于前沿技术的症状。我提出了漏洞报告


1
你好,感谢您的精准和行动,我希望有一天能找到解决这个问题的方法。目前,我使用了几个“hack”来避免破坏Dalvik的65k限制。 - Aymeric
引用的错误现在已标记为已修复。 - Tim Kist

12
运行以下Gradle命令以诊断和解决此问题:
./gradlew clean app:dependencies

这将以树形式列出应用程序中的所有依赖项。在结果中搜索重复的类,并添加。

compile('naughty.library') {
    exclude group: 'foo', module: 'bar'
}

去除重复项。


谢谢!感谢您展示如何诊断。这是我找到的唯一真正了解错误位置的方法。 - algarrobo

6

我最近遇到了这个错误,在查看了Android Studio中的“外部库”后,我发现我的一个库在两个版本号下被包含了。(在这种情况下它是wire-runtime 1.5.1和1.5.2)。

我建议您查看项目视图中的“外部库”,并查看是否有任何多余的库。它还包括传递依赖项,因此您可能会发现一些令人惊讶的东西。


2
我已经多次检查了外部库,确实没有发现任何相关的问题。到目前为止,我还没有重复的内容。 - Aymeric
3
关于这个问题,我无意中手动将一个 JAR 版本放在了 "libs/" 目录下(使用依赖 compile fileTree(dir: 'libs', include: '*.jar')),但后来又使用从 Maven 中获取的编译行再次引用了该库。解决方法是删除其中一个! - qix
1
同样的问题...由于没有重复的库,我没有注意到任何问题...然后我读到分析现在包含在Google Play服务中,并且我的项目中有一个jar引用。删除它解决了我的问题... - user754730
1
qix,如果可以的话,我会给那条评论点赞一百万次。你刚刚救了我的一天。 - A.Grandt

3

1. 更新 Google Play 服务。

2. 添加。

compile 'com.google.android.gms:play-services-fitness:8.1.0'
compile 'com.google.android.gms:play-services-wearable:8.1.0'

在build.gradle文件中,使用compile 'com.google.android.gms:play-services:8.1.0'的替代方案。

3.

defaultConfig {
    multiDexEnabled true
}

dependencies {
    compile 'com.android.support:multidex:1.0.1'
}

1
在我的情况下,问题出在Facebook Android SDK上。只需排除传递依赖即可:
compile('com.facebook.android:facebook-android-sdk:+') {
    exclude group: 'com.android.support', module: 'multidex'
}

在您的情况下,可能是其他一些依赖项 - 只需逐个排序,您就会找到具有传递性multidex依赖项的那一个。

0
tools:overrideLibrary="com.google.android.gms.location, com.google.android.gms.internal"

对我来说起作用了(我猜你应该用你所使用的谷歌库更改位置)


1
我应该在哪里做这个? - Partha Chakraborty
在清单文件中,它是用于 uses-sdk 项的标签。 <uses-sdk android:minSdkVersion="8" tools:overrideLibrary= ... /> - Meltzer
为什么这个解决方案特别适用于 java.util.zip.ZipException?而且 minSdkVersion 不应该在 gradle 中指定吗? - IgorGanapolsky

0

这种重复条目的错误通常发生在某个类在多个位置出现时。为了解决这个问题,简单地查找在项目中显示重复条目的类。它会显示出该类存在于多个位置的所有路径。在Windows中,使用CTRL+N键盘快捷键进行文件搜索。尝试删除其中一个库或文件,问题就会得到解决。


0
如果您启用了multiDex,应该停止在afterEvaluate {}中执行逻辑。多dex支持将为您处理主dex列表。

遗憾的是,删除那部分不会改变任何事情。我认为需要做的是找到并解决一些冲突的依赖关系。 - Aymeric
有些奇怪的事情正在发生,因为它试图在APK中打包一个.class文件,这实际上是不应该的,我不确定这是从哪里来的。它似乎与multi-dex无关。我的评论仍然适用于remove afterEvaluate {}(但出于另一个原因)。 - Xavier Ducrohet

0

你正在添加一个库,像这样
(A). compile files('libs/YOUR_LIBRARY.jar')
而且这个库包已经在你的代码中可用。
要么注释掉它,要么删除这行
//compile files('libs/YOUR_LIBRARY.jar')

如何知道你的项目中是否有重复的库副本:
解压缩你的 "YOUR_LIBRARY.jar" 并查看你的代码中是否有相同的类名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接