我们在我们的应用程序中使用multidex很长一段时间但最近使用最新更新它在android API< 19上失败了 例如模拟器与api 16 它是标准的java.lang.NoClassDefFoundError。
如果我为缺失的类定义了multidexKeepProguard,例如 java.lang.NoClassDefFoundError。 rx.plugins.RxJavaHooks异常
compile 'com.android.support:multidex:1.0.1'
然后它会在 不同的地方 失败,原因与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:JetBrains s.r.o的OpenJDK 64位服务器VM
编译选项
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')
}
构建工具信息:
./gradlew clean connectedPayGermanyCompatDebugAndroidTest
我尝试了从扩展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
要运行,请禁用即时运行
要重现多索引问题,请运行以下命令
{{1}}
在任何设备或API 16仿真器上运行在GTI8190上测试4.1.2失败由于java.lang.NoClassDefFoundError
,仪表运行失败有任何建议如何解决这个问题,直到我从Google小组获得更多信息?
答案 0 :(得分:2)
Google开发者解释
问题是从中引用的rx.plugins.RxJavaHooks类 CustomJunitRunner.onCreate()方法位于辅助dex文件中 主应用程序,您在类加载器获取之前访问它 完全打补丁。
当主应用程序和测试代码共享依赖关系时,我们会 将其从测试的依赖项中删除(正如我们所期望的那样) 可在主应用程序中找到)。但是,使用传统的multidex, 这导致了问题。
目前,有2种解决方法:
选项1确保rx.plugins.RxJavaHooks位于主dex中 创建一个文件multidexKeepProguard.pro并添加" -keep类 。rx.plugins **"
选项2从onCreate()中删除对RxJavaHooks的引用,然后移动 他们到onStart()(不确定这是否在你想要的时候完成 虽然): @覆盖 public void onStart(){ super.onStart(); //将调度程序连接到rxjava,以便espresso空闲资源可以正确获取它 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.** { *; }