仅在运行测试时出现DexIndexOverflowException

时间:2015-10-24 00:03:30

标签: android unit-testing gradle android-gradle proguard

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

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

4 个答案:

答案 0 :(得分:21)

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

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

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

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

  1. 更改Gradle版本配置以启用multidex
  2. 修改您的清单以引用MultiDexApplication类
  3. 修改您的应用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' 
    }
    

    在您的清单中,将 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>
    

    阅读官方文件 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尽可能使用代码。

答案 1 :(得分:3)

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

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

查找并排除重复的依赖项:打开终端并运行:

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没有)。希望它有所帮助。

答案 2 :(得分:1)

升级到gradle插件3.1.1为我修复了问题,如建议in this answer

答案 3 :(得分:-1)

如果您只需要对测试提供multidex支持,则只能在build.gradle中使用类似以下行的测试启用它:

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