multidex-启用了multidex的NoClassDefFoundError

时间:2019-04-23 01:44:48

标签: android kotlin multidex android-multidex

我的应用在21年前崩溃,出现java.lang.NoClassDefFoundError app.module.SomeClass错误。

我已经启用了Multidex:

build.gradle:

android {
    defaultConfig {
        ...
        multiDexEnabled true
    }
}

dependencies {
   ...
   implementation "androidx.multidex:multidex:2.0.1"
}

我的应用程序类:

class App : DaggerApplication() {
    ...
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }

在阅读了Declaring classes required in the primary DEX file之后,我创建了multidex-config.pro文件以在主DEX文件中包含app.module.**

-keep class app.module.** { *; }

并在build.gradle中注册它:

android {
  buildTypes {
    debug {
      ...
      multiDexKeepProguard file('multidex-config.pro')
    }
}

我通过检查build/intermediates/legacy_multidex_main_dex_list/debug/mainDexList.txt并分析调试apk(检查classes.dex是否包含app.module.SomeClass)来确认这一点。

但是我仍然遇到java.lang.NoClassDefFoundError app.module.SomeClass错误。

我还尝试了清理缓存,在不同的机器上运行(仅在没有Android Studio的情况下构建cli),禁用即时运行,指定javaMaxHeapSize,仅扩展MultiDexApplication等。

接下来我可以尝试什么?

6 个答案:

答案 0 :(得分:3)

我们在这里对此有更深入的了解:

https://issuetracker.google.com/issues/131100011

不幸的是,在21之前的设备上的某些Dalvik VM中存在一个错误,其中某些程序包的私有方法有时会被另一个程序包中的公共方法错误地覆盖。如果包私有方法是最终方法,则将导致以下形式的错误:

E/dalvikvm: Method Lcom/mycompany/MyViewModel;.clear overrides final Landroidx/lifecycle/ViewModel;.clear

在这里看来,这可能是打击您的原因。不幸的是,针对该特定问题的唯一解决方法是将您的“清除”方法重命名为其他名称,以便您不会遇到该不幸的VM错误。

答案 1 :(得分:1)

在您的应用gradle文件中添加此

android {
    ...
    dexOptions {
        jumboMode = true
        javaMaxHeapSize "4g"
     }
     defaultConfig {
         ...

javaMaxHeapSize

指定内存分配池的最大大小(以字节为单位)。此值必须是大于2 MB的1024的倍数。追加字母k或K表示千字节,或者追加m或M表示兆字节。默认值是在运行时根据系统配置选择的。

答案 2 :(得分:1)

尝试更改DaggerApplication的指令顺序:

override fun onCreate() {
    MultiDex.install(this)
    super.onCreate()
}

因为documentation的内容是:

  

警告:在MultiDex.install()完成之前,请勿通过反射或JNI执行MultiDex.install()或任何其他代码。 Multidex跟踪不会跟随这些调用,从而导致ClassNotFoundException或由于DEX文件之间的类分区不正确而导致验证错误。

答案 3 :(得分:1)

尝试

dexOptions {
            preDexLibraries = false
        }

答案 4 :(得分:1)

尝试以下步骤,希望对您有所帮助

dependencies { 
 compile 'com.android.support:multidex:1.0.1' 
}

配置您的源 在AndroidManifest.xml文件中声明MultiDexApplication类

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:name="android.support.multidex.MultiDexApplication">
</application>

如果我们无法扩展MultiDexApplication,则可以通过覆盖Application类中的attachBaseContext(Context base)方法来手动安装多个dex文件

public class HelloMultiDexApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
    }
@Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

在app / build.gradle中配置dexOptions

android {
    dexOptions {
        incremental true         
        javaMaxHeapSize "4g"
    }
}

在app / build.gradle中启用multidex

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' 
}

在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
        }
    }
}

在gradle.properties中增加gradle jvm构建

org.gradle.jvmargs=-Xmx4608M

答案 5 :(得分:1)

在为冰淇淋三明治(API 14)设备构建ADB时,我经常遇到这个问题。

对我有用的是disabling Android Studio's instant run