Android Espresso multidex失败

ori*_*inx 8 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.**{*;}
Run Code Online (Sandbox Code Playgroud)

然后它会在不同的地方失败,原因与NoClassDefFound相同

这是跑步者,应用程序和清单设置:

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

logcat的:

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

建立环境设置:

Android Studio 2.2.2 Build#AI-145.3360264,建于2016年10月18日JRE:1.8.0_112-release-b05 x86_64 JVM:JetJrains sro的OpenJDK 64位服务器VM

编译选项

compile 'com.android.support:multidex:1.0.1'
Run Code Online (Sandbox Code Playgroud)

构建工具信息:

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

我尝试了从扩展MultiDexApplication到自定义MultiDex.install(上下文)到使用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导致仪器运行失败

有任何建议如何解决这个问题,直到我从谷歌团队获得更多信息?

ori*_*inx 2

谷歌开发者的解释:

问题在于 CustomJunitRunner.onCreate() 方法引用的 rx.plugins.RxJavaHooks 类位于主应用程序的辅助 dex 文件中,并且您在类加载器完全修补之前访问它

当主应用程序和测试代码共享依赖项时,我们会将其从测试的依赖项中删除(因为我们希望它在主应用程序中可用)。然而,对于传统的 multidex,这会导致问题。

目前,有 2 个解决方法:

选项 1 通过创建文件 multidexKeepProguard.pro 并添加“-keep class rx.plugins.**”,确保 rx.plugins.RxJavaHooks 位于主 dex 中

选项 2 从 onCreate() 中删除对 RxJavaHooks 的引用,并将它们移至 onStart() (但不确定这是否在您需要时完成): @Override public void onStart() { super.onStart(); //将调度程序连接到rxjava,以便espresso空闲资源可以正确获取它 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')
        }
Run Code Online (Sandbox Code Playgroud)

你的 multidex proguard 文件应该包含在主 dex 文件中找不到的类,在我的例子中它是 RxJavaPlugin,所以我的 multidexproguard 文件包含:

-keep class rx.** { *; }
Run Code Online (Sandbox Code Playgroud)