仅在运行testing时出现DexIndexOverflowException

我可以在我的debugging和发布版本中成功构build和运行我的Android应用程序,没有任何问题。 然而,当我尝试运行我的新unit testing(我从来没有他们之前),我得到了可怕的DexIndexOverflowException 。 我怀疑ProGuard没有在我的unit testing中运行,但它是我的正常debugging和发布buildTypes。

在unit testing运行configuration中运行ProGuard需要做什么? 我通过Gradle文档, ProGuard文档和Android Studio文档search了解这一点,但我什么也没find。

 com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 

Android应用程序(APK)文件包含Dalvik Executable(DEX)文件forms的可执行字节码文件,其中包含用于运行应用程序的编译代码。 Dalvik Executable规范将单个DEX文件中可引用的方法总数限制为65,536个,包括您自己代码中的Android框架方法,库方法和方法。 超越此限制要求您configuration您的应用程序生成过程以生成多个DEX文件(称为multidexconfiguration)。

Android SDK Build Tools 21.1及更高版本中提供的Gradle Android插件支持multidex作为构buildconfiguration的一部分。 在尝试为您的应用程序configurationmultidex之前,请确保您使用SDK Manager将Android SDK Build Tools工具和Android Support Repository更新到最新版本。

设置您的应用程序开发项目以使用multidexconfiguration需要您对应用程序开发项目进行一些修改。 特别是你需要执行以下步骤:

  1. 改变你的Gradle构buildconfiguration来启用multidex
  2. 修改您的清单以引用MultiDexApplication类

修改您的应用程序Gradle构build文件configuration以包含支持库并启用multidex输出。

  android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { ... minSdkVersion 14 targetSdkVersion 25 ... // Enabling multidex support. multiDexEnabled true } ... } dependencies { compile 'com.android.support:multidex:1.0.1' } 

在清单中,将MultiDexApplication类从multidex支持库添加到应用程序元素。

 <?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> 

阅读关于MultiDex的官方文档

如果您的Application类正在扩展某个其他类,并且您不想或不能更改它,请按如下所示override attachBaseContext()

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

然后

 <?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=".MyApplication"> </application> </manifest> 

结论

虽然图书馆在大多数情况下修复了DEX 64K问题,但它应该被视为最后的手段。 在尝试使用它之前,您应该审核您的项目以获取不需要的依赖关系,并尽可能多地使用ProGuard删除未使用的代码。

发生错误可能是因为你的项目和库中有太多的函数。 您可以:
作为@Intellij Amiya的答案启用multiple dex
– 检查库:仅指定您的应用使用的特定Google Play服务API,而不是全部。

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

查找并排除重复的依赖关系:打开您的terminal并运行:

gradle -q dependencies

它会显示一个列表,如下所示:

 +--- com.android.support:appcompat-v7:23.0.1 | \--- com.android.support:support-v4:23.0.1 | \--- com.android.support:support-annotations:23.0.1 +--- :dputility_library-1.1.2: +--- com.google.android.gms:play-services-ads:7.5.0 | +--- com.google.android.gms:play-services-base:7.5.0 | | \--- com.android.support:support-v4:22.0.0 -> 23.0.1 (*) | \--- com.google.android.gms:play-services-analytics:7.5.0 | \--- com.google.android.gms:play-services-base:7.5.0 (*) +--- com.jakewharton:butterknife:7.0.1 +--- com.afollestad:material-dialogs:0.7.6.0 | +--- com.android.support:support-v4:22.2.0 -> 23.0.1 (*) | +--- com.android.support:appcompat-v7:22.2.0 -> 23.0.1 (*) | +--- com.android.support:recyclerview-v7:22.2.0 | | +--- com.android.support:support-annotations:22.2.0 -> 23.0.1 | | \--- com.android.support:support-v4:22.2.0 -> 23.0.1 (*) | \--- com.android.support:support-annotations:22.2.0 -> 23.0.1 

你可以看到一些依赖(*),你可以从你的gradle依赖中排除它:

 compile('com.google.android.gms:play-services-ads:7.5.0') { exclude module: 'support-v4' exclude module: 'play-services-base' } 

实际上,对我来说排除方法是有效的(多个dex不)。 希望它有帮助。

如果你只需要multidex对testing的支持,那么你可以在你的build.gradle只针对像下面这样的行进行testing:

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