Android Эспрессо мультидекс сбой

Мы используем мультидекс в нашем приложении в течение длительного времени, но в последнее время с последним обновлением происходит сбой на Android API <19, например, эмулятор с API 16. Это стандартный java.lang.NoClassDefFoundError.

Если я определю multidexKeepProguard для отсутствующего класса, например, java.lang.NoClassDefFoundError. rx.plugins.RxJavaHooks исключение

-keep class rx.plugins.**{*;}

тогда он просто потерпит неудачу в другом месте по той же самой причине NoClassDefFound

Вот бегун, приложение и настройка манифеста:

https://gist.github.com/originx/1890599b57b0ee3e14a85a4732301cd9

Logcat:

https://gist.github.com/originx/887f80d405334f1903b3024eb5cd1024

Настройка среды сборки:

Android Studio 2.2.2, сборка #AI-145.3360264, построена 18 октября 2016 г. JRE: 1.8.0_112-release-b05 x86_64 JVM: 64-битная виртуальная машина OpenJDK от JetBrains sro

Варианты компиляции

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

Информация о сборке инструментов:

   classpath 'com.android.tools.build:gradle:2.2.2'
   compileSdkVersion 25
   buildToolsVersion '25'


   defaultConfig {
        applicationId "app.packagename.com"

         minSdkVersion 16
        targetSdkVersion 25

        testInstrumentationRunner "de.payback.app.CustomAndroidJUnitRunner"
        multiDexEnabled true
    }

 dexOptions {
        jumboMode true
        preDexLibraries false
        javaMaxHeapSize "4g"
        maxProcessCount = 8
    }

  debug {
            applicationIdSuffix '.debug'
            versionNameSuffix '-debug'
            signingConfig signingConfigs.debug
            minifyEnabled false
            shrinkResources debugShrinkResourcesEnabled
            proguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguardRules/proguard-rules.pro', '../proguardRules/proguard-debug-rules.pro'
          //  multiDexKeepProguard file('../proguardRules/multidex-proguard.pro')
            testProguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguardRules/proguard-rules.pro', '../proguardRules/proguard-debug-test-rules.pro'
            testCoverageEnabled false
        }
        release {
            minifyEnabled true
            shrinkResources true
            testProguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguardRules/proguard-rules.pro'
            proguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguardRules/proguard-rules.pro'
          //  multiDexKeepProguard file('../proguardRules/multidex-proguard.pro')
        }

Я перепробовал все: от расширения MultiDexApplication до пользовательского MultiDex.install (context) до использования MultiDexRunner.

всегда одни и те же результаты

при использовании файла multidexkeepproguard для классов, которые обычно не обнаруживаются, они находятся в основном файле dex, но, конечно, чего-то не хватает, что указывает на то, что multidex не был правильно установлен и инициализирован

Отчет об ошибках Google:

https://code.google.com/p/android/issues/detail?id=228449

репо для воспроизведения проблемы можно найти здесь:

https://github.com/originx/multidex/tree/master

Для запуска, пожалуйста, отключите мгновенный запуск

Чтобы воспроизвести проблему мультидекса, выполните следующую команду

./gradlew clean connectedPayGermanyCompatDebugAndroidTest

выполнить на любом устройстве или эмуляторе API 16. Тесты на GTI8190 4.1.2 завершились неудачно. Сбой запуска инструментария из-за java.lang.NoClassDefFoundError

Какие-нибудь предложения, как обойти это, пока я не получу больше информации от команды Google?

1 ответ

Решение

Объяснение от Google dev:

Проблема заключается в том, что класс rx.plugins.RxJavaHooks, на который ссылается метод CustomJunitRunner.onCreate(), находится во вторичном файле dex основного приложения, и вы обращаетесь к нему до того, как загрузчики классов будут полностью исправлены.

Когда основное приложение и тестовый код разделяют зависимость, мы удалим ее из зависимостей теста (поскольку мы ожидаем, что она будет доступна в основном приложении). Однако с устаревшим мультидексом это вызывает проблемы.

В настоящее время есть 2 обходных пути:

Вариант 1 Убедитесь, что rx.plugins.RxJavaHooks находится в главном разделе, создав файл multidexKeepProguard.pro и добавив "-keep class rx.plugins. **"

Вариант 2 Удалите ссылки на RxJavaHooks из onCreate () и переместите их в onStart() (хотя не уверен, что это выполняется, когда вы этого хотите): @Override public void onStart() { super.onStart(); // подключаем планировщики к rxjava, чтобы эспрессо-ресурсы на холостом ходу могли правильно его получить RxJavaHooks.setOnComputationScheduler(current -> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); RxJavaHooks.setOnIOScheduler(текущий -> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); RxJavaHooks.setOnNewThreadScheduler(текущий -> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); }

Решение

Временное решение

Таким образом, текущий обходной путь будет либо использовать файл multidexKeepProguard.pro и в вашей конфигурации отладки указать на этот файл:

 debug {
            applicationIdSuffix '.debug'
            multiDexKeepProguard file('../proguardRules/multidex-proguard.pro')
        }

Ваш файл multidex proguard должен содержать классы, которых нет в основном файле dex, в моем случае это был RxJavaPlugin, поэтому мой файл multidexproguard содержит:

-keep class rx.** { *; }
Другие вопросы по тегам