仅在运行测试时出现DexIndexOverflowException

Joh*_* D. 12 android unit-testing proguard gradle android-gradle-plugin

我可以在我的调试和发布版本中成功构建和运行我的Android应用程序,没有任何问题.然而,当我尝试运行我的新单元测试(之前从未有过它)时,我得到了可怕的DexIndexOverflowException.我怀疑ProGuard是不是运行我的单元测试,但它是我正常的调试和发布buildTypes.

ProGuard在单元测试运行配置中运行需要做什么?我搜索了Gradle文档,ProGuard文档和Android Studio文档来解决这个问题但我一无所获.

Int*_*iya 21

com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 
Run Code Online (Sandbox Code Playgroud)

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

Android SDK Build Tools 21.1及更高版本中提供的Gradle Android插件支持multidex作为构建配置的一部分.在尝试为multidex配置应用程序之前,请确保使用SDK Manager将Android SDK构建工具工具和Android支持存储库更新到最新版本.

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

  1. 更改Gradle构建配置以启用multidex
  2. 修改清单以引用MultiDexApplication类

修改您的应用程序Gradle构建文件配置以包括支持库并启用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.3' 
}
Run Code Online (Sandbox Code Playgroud)

在清单中MultiDexApplication,将multidex支持库中的类添加到application元素中.

<?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>
Run Code Online (Sandbox Code Playgroud)

阅读有关MultiDex的官方文档

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

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

然后

<?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>
Run Code Online (Sandbox Code Playgroud)

结论

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

  • 我真的不认为这个答案能解决问题的根源。听起来用户已经完全意识到了与非测试版本有关的多dex问题。为什么要测试版本而不是生产版本?如何为测试版本启用proguard?我的猜测是,第二个问题听起来像是一个坏主意。 (2认同)