DexIndexOverflowException только при выполнении тестов

Я могу успешно создать и запустить приложение для Android в своих вариантах отладки и выпуска без проблем. Тем не менее, когда я пытаюсь запустить свои новые модульные тесты (у меня их раньше не было), я получаю страшный DexIndexOverflowException. Я подозреваю, что ProGuard не запускается с моими модульными тестами, но это связано с моими стандартными отладчиками и версиями buildTypes.

Что мне нужно сделать для запуска ProGuard в моей конфигурации unit test? Я просмотрел документацию Gradle, документацию ProGuard и документацию по Android Studio, чтобы понять это, но я ничего не нашел.

Ответ 1

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

Файлы приложения Android (APK) содержат исполняемые файлы байт-кода в форма файлов Dalvik Executable (DEX), которые содержат скомпилированные код, используемый для запуска вашего приложения. Пределы спецификации Дейвика Дейвика общее количество методов, на которые можно ссылаться в одном DEX файл до 65 536, включая методы Android, методы библиотеки, и методы в вашем собственном коде. Чтобы преодолеть этот предел, вы настраиваете процесс создания приложений для создания более одного DEX файл, известный как многоэлементная конфигурация.

Плагин Android для Gradle, доступный в Android SDK Build Tools 21.1 и выше, поддерживает multidex как часть вашей конфигурации сборки. Перед настройкой приложения для мультидекса убедитесь, что вы обновили инструменты Android SDK Build Tools и репозиторий поддержки Android до последней версии с помощью диспетчера SDK.

Настройка проекта разработки приложений для использования конфигурации с несколькими приложениями требует внесения нескольких изменений в проект разработки приложений. В частности, вам необходимо выполнить следующие шаги:

  • Измените конфигурацию сборки Gradle, чтобы включить multidex
  • Изменить манифест для ссылки на класс 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.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.

Ответ 2

ошибка возникает, возможно, из-за слишком большого количества функций в ваших проектах и ​​библиотеке. Ты можешь:
- Включить multiple dex как @Intellij Amiya ответ
- Проверьте библиотеки:, указав только те API-интерфейсы служб Google Play, которые используются вашим приложением, а не все.

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 нет). Надеюсь, что это поможет.

Ответ 3

Если вам нужна только поддержка multidex для тестов, вы можете включить ее только для тестов с строкой, подобной следующей в build.gradle:

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