更新到最新的AppCompat和Support库后,出现DexIndexOverflowException问题

74

我正在通过 gradle 使用以下设置:

compileSdkVersion 21
ANDROID_BUILD_MIN_SDK_VERSION=14
ANDROID_BUILD_TARGET_SDK_VERSION=21
ANDROID_BUILD_TOOLS_VERSION=21.0.2
ANDROID_BUILD_SDK_VERSION=21

我在gradle文件中也有以下设置:

compile 'com.android.support:support-annotations:21.0.0'
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'com.android.support:support-v4:21.0.0'

我总是会遇到错误UNEXPECTED TOP LEVEL EXCEPTION,但是当我将21.0.0改成20.0.0时,它就能正常工作了...但我无法访问Android API 21选项。这里有什么问题吗?我该如何编译而不出现异常?我没有在其他gradle项目(例如Facebook等)之外找到支持的jar包。

以下是完整的堆栈跟踪:

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
    at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:502)
    at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:283)
    at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491)
    at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168)
    at com.android.dx.merge.DexMerger.merge(DexMerger.java:189)
    at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:302)
    at com.android.dx.command.dexer.Main.run(Main.java:245)
    at com.android.dx.command.dexer.Main.main(Main.java:214)
    at com.android.dx.command.Main.main(Main.java:106)

你是否从SDK管理器中下载了所有的库和工具? - Gabriele Mariotti
是的,我只是将我的应用程序从API 19更新到21。包括之前版本的所有库和21的所有新库。 - KVISH
重复的https://dev59.com/wmUp5IYBdhLWcg3wh39W - Alex Lipov
7个回答

148

这条信息听起来说明你的项目太大了。

你的方法太多了。Dex格式只允许最多 65536 个方法

从 gradle 插件 0.14.0 和 Build Tools 21.1.0 开始,你可以使用multidex支持

只需在build.gradle中添加以下几行:

android {

    defaultConfig {
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

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

同时在您的Manifest文件中的应用程序元素中添加来自multidex支持库的MultiDexApplication类。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication"> 
        ...
    </application>
</manifest>

如果您正在使用自己的Application类,请将父类从Application更改为MultiDexApplication


6
在你的 build.gradle 文件的 defaultConfig 中添加 multiDexEnabled true,以支持多 Dex 文件。 - Elhanan Mishraky
我不使用build.gradle文件来构建我的应用程序。有没有解决这个问题的方法? - Ashokchakravarthi Nagarajan
我不得不使用@georgehardcore答案中的AndroidManifest.xml更改才能使其正常工作。 - The Unknown Dev
我不得不在Android清单文件中更改标签为<meta-data android:name="android.support.multidex.MultiDexApplication" android:value="true"/>,才能使它对我起作用。我正在使用多模块项目...如果我没有这样做,我会遇到这个错误:INSTALL_PARSE_FAILED_MANIFEST_MALFORMED - Eric
1
谢谢,这非常重要,帮了我很多。 - Weverton Peron
显示剩余4条评论

45

1) 在应用程序的 build.gradle 文件中添加依赖项

compile 'com.android.support:multidex:1.0.2'

2) 如果您不覆盖Application类,则请编辑您的清单文件,将android:name在中设置如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
            android:name="android.support.multidex.MultiDexApplication" >
        ...
    </application>
</manifest>

如果您要重写Application类,请按以下方式将其更改为扩展MultiDexApplication(如果可能):

public class MyApplication extends MultiDexApplication { ... }

如果您覆盖了Application类但无法更改基类,则可以改为覆盖attachBaseContext()方法并调用MultiDex.install(this)来启用Multidex:

public class MyApplication extends SomeOtherApplication {
  @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     MultiDex.install(this);
  }
}

3) 在 build.gradle 的 defaultConfig 中添加 multidex 支持。

defaultConfig {
        ...
        minSdkVersion 16
        targetSdkVersion 26
        ...
        // Enabling multidex support.
        multiDexEnabled true
    }
...

完美!@georgehardcore - benchuk
@georgehardcore:我在我的Android Eclipse项目中使用了第二个点,但仍然显示相同的错误。 - Nageswara Rao.CH
如果您正在使用google-play-services库,请尝试将其拆分。例如,如果您使用分析和gcm,请将它们作为单独的模块插入基本模块中,如下所示:compile 'com.google.android.gms:play-services-base:8.1.0' compile 'com.google.android.gms:play-services-analytics:8.1.0' compile 'com.google.android.gms:play-services-gcm:8.1.0' - georgehardcore
@georgehardcore 不确定是否需要第二步,因为它在我的应用程序上没有帮助我。所以我跳过了它,其余的步骤都很好用! - Vu Nguyen
对我来说,它可以工作,但在清单中没有将Application类更改为MultiDexApplication,也没有MyApplication类。 - Amt87

3

在使用MultiDex之前

如果你的解决方案太大(使用MultiDex),或者你在编译并将一些不必要的内容包含到项目中。我在我的小项目中遇到了这个问题。下面是我修复它的方法:

我从build.gradle中删除了以下内容:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

我手动从应用程序根目录中删除了构建文件夹。问题已解决。

2

请按照此链接的指南,解决65K限制问题。

我通过设置multiDexEnabled true并将我的应用程序扩展为class MyApp extends MultiDexApplication来在gradle中解决了这个问题。


0

首先确保在app/build.cradle中启用了代码压缩:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.config
    }
    debug {
        signingConfig signingConfigs.config
    }
}

如果这不能解决问题,为您的应用启用multidex build

0

当我将整个Google Play服务API包编译到我的应用程序中时,我遇到了这个问题。我通过使用选择性API解决了这个问题。

例如,要仅包括Google Fit和Android Wear API,请在您的build.gradle文件中替换以下行:

compile 'com.google.android.gms:play-services:11.0.2'

使用这些代码行:

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

问题在以下链接中解释。

0

我只是在build.gradle文件中注释掉了编译filetree(include: ['*.jar'], dir: 'libs')(如上所建议),然后重新构建项目。编译没有任何错误。我不需要移动任何文件夹。


1
请忽略我的评论——即使我手动删除了构建文件夹,后续的重建仍会生成相同的原始错误。 - Earl Allen

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