multidex - NoClassDefFoundError with multidex enabled

China☆狼群 提交于 2020-01-13 18:25:07

问题


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 before MultiDex.install() is complete. Multidex tracing will not follow those calls, causing ClassNotFoundException 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!