Android Espresso multidex 失败
Android Espresso multidex fail
我们在我们的应用程序中使用 multidex 很长时间了,但最近的最新更新在 android API <19 上失败了
例如api 16 的模拟器
是标准的 java.lang.NoClassDefFoundError.
如果我定义 multidexKeepProguard 用于丢失 class 例如
java.lang.NoClassDefFoundError。 rx.plugins.RxJavaHooks 异常
-keep class rx.plugins.**{*;}
然后它将在不同的地方失败,原因与NoClassDefFound
相同
这是 运行ner、应用程序和清单设置:
https://gist.github.com/originx/1890599b57b0ee3e14a85a4732301cd9
Logcat:
https://gist.github.com/originx/887f80d405334f1903b3024eb5cd1024
构建环境设置:
Android Studio 2.2.2
构建 #AI-145.3360264,构建于 2016 年 10 月 18 日
JRE: 1.8.0_112-release-b05 x86_64
JVM:JetBrains 的 OpenJDK 64 位服务器虚拟机 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
的所有方法
总是相同的结果
如果对通常找不到的 classes 使用 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 GTI8190 4.1.2 上的 16 个模拟器测试失败 Instrumentation 运行 由于 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.** { *; }
我们在我们的应用程序中使用 multidex 很长时间了,但最近的最新更新在 android API <19 上失败了 例如api 16 的模拟器 是标准的 java.lang.NoClassDefFoundError.
如果我定义 multidexKeepProguard 用于丢失 class 例如 java.lang.NoClassDefFoundError。 rx.plugins.RxJavaHooks 异常
-keep class rx.plugins.**{*;}
然后它将在不同的地方失败,原因与NoClassDefFound
相同这是 运行ner、应用程序和清单设置:
https://gist.github.com/originx/1890599b57b0ee3e14a85a4732301cd9
Logcat:
https://gist.github.com/originx/887f80d405334f1903b3024eb5cd1024
构建环境设置:
Android Studio 2.2.2 构建 #AI-145.3360264,构建于 2016 年 10 月 18 日 JRE: 1.8.0_112-release-b05 x86_64 JVM:JetBrains 的 OpenJDK 64 位服务器虚拟机 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
的所有方法总是相同的结果
如果对通常找不到的 classes 使用 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 GTI8190 4.1.2 上的 16 个模拟器测试失败 Instrumentation 运行 由于 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.** { *; }