Android Espresso multidex失败 [英] Android Espresso multidex fail

查看:101
本文介绍了Android Espresso multidex失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在应用程序中使用multidex的时间很长,但是最近进行了最新更新,因此在Android API< 19上失败 例如带有API 16的仿真器 这是标准的java.lang.NoClassDefFoundError.

We use multidex in our app for a long time but recently with latest update it fails on android API <19 e.g. emulator with api 16 It is standard java.lang.NoClassDefFoundError.

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

If I define multidexKeepProguard for missing class e.g. java.lang.NoClassDefFoundError. rx.plugins.RxJavaHooks exception

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

然后它将在 另一个地方 中失败,其原因与NoClassDefFound

then it will just fail in a different place with the same reason NoClassDefFound

以下是跑步者,应用和清单设置:

Here is the runner, app and manifest setup:

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:JetBrains s.r.o

Android Studio 2.2.2 Build #AI-145.3360264, built on October 18, 2016 JRE: 1.8.0_112-release-b05 x86_64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

编译选项

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的所有操作

I tried everything from extending MultiDexApplication, to custom MultiDex.install(context) to using MultiDexRunner

总是有相同的结果

如果对通常找不到的类使用multidexkeepproguard文件,则它们位于主dex文件中,但是当然缺少其他内容,表明未正确安装和初始化multidex

if using multidexkeepproguard file for classes which are usually not found then they are in main dex file but of course something else is missing which indicates that multidex was not properly installed and initialized

Google错误报告:

Google bug report:

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

重现该问题的回购可以在这里找到:

repo to reproduce the issue can be found here:

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

要运行,请禁用即时运行

To run please disable instant run

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

To reproduce multidex issue please run following command

./gradlew clean connectedPayGermanyCompatDebugAndroidTest

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

run on any device or API 16 emulator Tests on GTI8190 4.1.2 failed Instrumentation run failed due to java.lang.NoClassDefFoundError

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

Any suggestions how to work around this until I get more info from the Google team?

推荐答案

Google开发者的解释:

问题是从 CustomJunitRunner.onCreate()方法位于的辅助dex文件中 主应用,您正在访问类加载器之前 完全修补.

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.

当主应用程序和测试代码共享依赖项时,我们将 从测试的依赖项中删除它(正如我们期望的那样) 在主应用程序中可用).但是,使用旧版multidex, 这会引起问题.

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:

选项1确保rx.plugins.RxJavaHooks位于主dex中,方法是: 创建文件multidexKeepProguard.pro并添加"-keep类 rx.plugins.**"

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

选项2从onCreate()中删除对RxJavaHooks的引用,然后移动 他们到onStart()(不确定何时完成此操作) 尽管): @Override 公共无效onStart(){ super.onStart(); //将调度程序连接到rxjava,以便浓缩咖啡空闲的资源可以正确获取它 RxJavaHooks.setOnComputationScheduler(当前-> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); RxJavaHooks.setOnIOScheduler(当前-> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); RxJavaHooks.setOnNewThreadScheduler(当前-> Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)); }

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文件,然后在您的调试配置中指向该文件:

Solution

Workaround

So current workaround would be either use multidexKeepProguard.pro file and in your debug config point to that file:

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

您的multidex proguard文件应该包含在主dex文件中找不到的类,在我的情况下是RxJavaPlugin,所以我的multidexproguard文件包含:

Your multidex proguard file should contain classes which are not being found in the main dex file, in my case it was RxJavaPlugin, so my multidexproguard file contains:

-keep class rx.** { *; }

这篇关于Android Espresso multidex失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆