Android Espresso multidex 失败

标签 android android-espresso android-multidex

我们在我们的应用程序中使用 multidex 很长时间了,但最近更新后它在 android API <19 上失败了 例如带有api 16的模拟器 它是标准的 java.lang.NoClassDefFoundError。

如果我为缺少的类定义 multidexKeepProguard,例如 java.lang.NoClassDefFoundError。 rx.plugins.RxJavaHooks 异常

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

然后它将在不同的地方以相同的原因 NoClassDefFound 失败

这是运行器、应用程序和 list 设置:

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

日志:

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

构建环境设置:

安卓工作室 2.2.2 构建 #AI-145.3360264,构建于 2016 年 10 月 18 日 JRE:1.8.0_112-release-b05 x86_64 JVM:JetBrains s.r.o 的 OpenJDK 64 位服务器 VM

编译选项

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

可以在此处找到重现问题的 repo:

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

要运行请禁用即时运行

要重现 multidex 问题,请运行以下命令

./gradlew clean connectedPayGermanyCompatDebugAndroidTest

在任何设备或 API 16 模拟器上运行 GTI8190 4.1.2 上的测试失败由于 java.lang.NoClassDefFoundError,仪器运行失败

在我从 Google 团队获得更多信息之前,有什么解决此问题的建议吗?

最佳答案

Google 开发人员的解释:

The issue is that the rx.plugins.RxJavaHooks class referenced from the CustomJunitRunner.onCreate() method is in the secondary dex file of the main app, and you are accessing it before the class loaders get fully patched.

When the main application and test code share a dependency, we will remove it from the test's dependencies (as we expect it to be available in the main application). However, with legacy multidex, this is causing problems.

Currently, there are 2 workarounds:

Option 1 Ensure the rx.plugins.RxJavaHooks is in the main dex by creating a file multidexKeepProguard.pro and adding "-keep class rx.plugins.**"

Option 2 Remove references to RxJavaHooks from onCreate(), and move them to onStart() (not sure if this accomplishes when you want though): @Override public void onStart() { super.onStart(); //hook up schedulers to rxjava so espresso idling resouces can fetch it properly RxJavaHooks.setOnComputationScheduler(current -> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); RxJavaHooks.setOnIOScheduler(current -> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); RxJavaHooks.setOnNewThreadScheduler(current -> 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.** { *; }

关于Android Espresso multidex 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40867407/

相关文章:

java - java.awt.geom.Area 的 android 等价物是什么?

android - 使用抽屉导航中的 fragment 来叠加 Activity

android - Espresso - 验证 TextView 内容 Android

Android 测试发布版本

java - 如何在 onResume() 方法中将 imageButtons 设置为 VISIBLE?

android - 如何使用 Espresso 打开抽屉导航?

java - Android - MultiDex 安装

android multidex 实现

android - 使用libgdx应用程序在Eclipse中启用Multidex

android - 如何通过 LatLng 点的 ArrayList 为标记设置动画?