问题
My app is crashing on pre-21 with java.lang.NoClassDefFoundError app.module.SomeClass
error.
I already have Multidex enabled:
build.gradle:
android {
defaultConfig {
...
multiDexEnabled true
}
}
dependencies {
...
implementation "androidx.multidex:multidex:2.0.1"
}
My Application class:
class App : DaggerApplication() {
...
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
After reading about Declaring classes required in the primary DEX file I created multidex-config.pro
file to include app.module.**
in primary DEX file:
-keep class app.module.** { *; }
And registered it in build.gradle:
android {
buildTypes {
debug {
...
multiDexKeepProguard file('multidex-config.pro')
}
}
I confirmed it by checking build/intermediates/legacy_multidex_main_dex_list/debug/mainDexList.txt
and analyzing the debug apk (checking whether classes.dex
includes app.module.SomeClass
).
But I'm still getting java.lang.NoClassDefFoundError app.module.SomeClass
error.
I also tried cleaning caches, running on different machines (cli build only without Android Studio), disabling instant run, specifying javaMaxHeapSize
, just extending MultiDexApplication
and etc.
What can I try next?
回答1:
We had a deeper look at this here:
https://issuetracker.google.com/issues/131100011
There is an unfortunate bug in some Dalvik VMs on pre-21 devices where package private methods were sometimes incorrectly overriden by public methods in another package. If the package private method is final, that will then lead to errors of the form:
E/dalvikvm: Method Lcom/mycompany/MyViewModel;.clear overrides final Landroidx/lifecycle/ViewModel;.clear
It looks like that could be what is hitting you here. Unfortunately, the only workaround for that particular issue is to rename your "clear" method to something else so that you do not hit this unfortunate VM bug.
回答2:
Try below steps hope it will help you
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
Config your source Declare MultiDexApplication class in AndroidManifest.xml file
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="android.support.multidex.MultiDexApplication">
</application>
If we can’t extend MultiDexApplication we can install multiple dex files manually by overriding attachBaseContext(Context base) method in our Application class
public class HelloMultiDexApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
Config dexOptions in app/build.gradle
android {
dexOptions {
incremental true
javaMaxHeapSize "4g"
}
}
Enable multidex in app/build.gradle
android {
defaultConfig {
multiDexEnabled true
}
}
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = ['--multi-dex']
} else {
dx.additionalParameters += '--multi-dex'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
Disabled pre-dexing each module at the end of root build.gradle
subprojects {
project.plugins.whenPluginAdded { plugin ->
if ("com.android.build.gradle.AppPlugin".equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = false
} else if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = false
}
}
}
Increase gradle jvm build in gradle.properties
org.gradle.jvmargs=-Xmx4608M
回答3:
In your app gradle file add this
android {
...
dexOptions {
jumboMode = true
javaMaxHeapSize "4g"
}
defaultConfig {
...
javaMaxHeapSize
Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is chosen at runtime based on system configuration.
回答4:
try changing the order of instructions for DaggerApplication
:
override fun onCreate() {
MultiDex.install(this)
super.onCreate()
}
because the documentation reads:
Caution: Do not execute
MultiDex.install()
or any other code through reflection or JNI beforeMultiDex.install()
is complete. Multidex tracing will not follow those calls, causingClassNotFoundException
or verify errors due to a bad class partition between DEX files.
回答5:
Try this
dexOptions {
preDexLibraries = false
}
回答6:
I use to have this issue when making ADB builds for ice cream sandwich (API 14) devices.
What worked for me was disabling Android Studio's instant run.
来源:https://stackoverflow.com/questions/55803196/multidex-noclassdeffounderror-with-multidex-enabled