SDK 21以下版本出现NoClassDefFoundError错误

24

我刚刚在我的应用程序中遇到了一个尴尬的错误。

在我的Nexus 5/7上,运行Android 5.0.1/5.0.2,一切正常。 但是,如果我尝试在早期版本的设备上运行完全相同的代码(已测试4.4.4和4.3),我会收到以下错误:

03-13 13:49:41.140  21714-21714/? E/dalvikvm﹕ Could not find class 'com.default.package.application.model.Appcomponent', referenced from method com.default.package.application.controller.DatabaseHandler.getScreenComponents
03-13 13:49:41.140  21714-21714/? E/dalvikvm﹕ Could not find class 'android.support.v7.app.ActionBarActivityDelegate$1', referenced from method android.support.v7.app.ActionBarActivityDelegate.<init>
03-13 13:49:41.140  21714-21714/? E/dalvikvm﹕ Could not find class 'android.support.v7.app.ActionBarActivityDelegateHC', referenced from method android.support.v7.app.ActionBarActivityDelegate.createDelegate
03-13 13:49:41.140  21714-21714/? E/dalvikvm﹕ Could not find class 'android.support.v7.app.ActionBarActivityDelegateBase', referenced from method android.support.v7.app.ActionBarActivityDelegate.createDelegate
03-13 13:49:41.150  21714-21714/? E/dalvikvm﹕ Could not find class 'android.support.v7.app.ActionBarActivityDelegate$ActionBarDrawableToggleImpl', referenced from method android.support.v7.app.ActionBarActivityDelegate.getDrawerToggleDelegate
03-13 13:49:41.150  21714-21714/? E/dalvikvm﹕ Could not find class 'android.support.v7.internal.view.SupportMenuInflater', referenced from method android.support.v7.app.ActionBarActivityDelegate.getMenuInflater
03-13 13:49:41.150  21714-21714/? E/dalvikvm﹕ Could not find class 'android.support.v7.app.ActionBarActivityDelegate$ActionBarDrawableToggleImpl', referenced from method android.support.v7.app.ActionBarActivityDelegate.getV7DrawerToggleDelegate
03-13 13:49:41.150  21714-21714/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.default.package, PID: 21714
    java.lang.NoClassDefFoundError: android.support.v7.app.ActionBarActivityDelegateHC

我已经尝试将support.v7库添加为jar文件,但没有任何改变。 但是既然它可以在Lollipop设备上运行,这就没有意义了。

可能存在一些与Dalvik/Art更改有关的问题吗? 或者可能是因为我不得不使用com.android.support:multidex:1.0.0,因为这是一个相当大的应用程序。

更新: 我尝试删除一些依赖项以使方法数少于65k的限制。之后,该应用在4.4.4和4.3设备上运行。 启用multidex支持所做的全部工作只是设置

multiDexEnabled true
在defaultConfig部分中添加

compile 'com.android.support:multidex:1.0.0'

在我的 build.gradle 的依赖项部分下面。

不知道为什么这会导致在旧的 Android 版本上出现这些问题?


1
在Eclipse中创建新的棒棒糖项目,并将其AppCompat添加到该项目中。 - karan
1
那个 com.default.package.application.model.appcomponent 是从哪里来的? - Jonas Czech
我尝试在Android Studio中创建一个新项目,并添加所有现有的源代码,但仍然遇到相同的问题。 com.default.package只是我的实际包名称的占位符。 - user2700475
3个回答

43

我通过将这个添加到我的Application类来解决了问题。

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

似乎对于 Android 版本 5 之前的版本是必需的。


1
你是否也在扩展你的Application类为MultiDexApplication?"public class App extends MultiDexApplication "...呢? - sirvon
3
公共类MyApplication继承自MultiDexApplication类:@Override注释的attachBaseContext方法被覆盖,它调用基类的同名方法并传递参数base。接着,MultiDex.install(this)方法被调用以安装多Dex支持。 - sonida
啊...不小心点了赞 :( 它仍然不能在Kitkat版本之前的版本中工作。 - Narendra Singh
已经为我解决了问题,但是如果你正在使用Robolectric,那么单元测试可能会失败。 我在这里回答了一个类似的问题(https://dev59.com/RZjga4cB1Zd3GeqPIVBd),并提供了一些额外的链接和信息来解决关于Multidex的几个问题。 - P Kuijpers
谢谢你的解决方案,我正在尝试在我的React Native项目中使用相同的东西。但是我遇到了关于appOpsManager的错误。你有什么想法吗? - Niloufar

12

这将有三种方式实现。

  1. 如@FireZenk所指出的,你可以在你的AndroidManifest.xml中将这个类声明为应用程序。
<application android:name="android.support.multidex.MultiDexApplication">

实际上,使用Android Gradle插件版本0.14.0和构建工具版本21.1.0时,当您在defaultConfig、ProductFlavor或BuildType中指定multiDexEnabled为true时,它会自动将依赖项包含到com.android.support:multidex:1.0.0中。 您可以使用androidDependencies任务或运行./gradlew -q android:dependencies命令(android:是我的android模块)来检查。因此,无需显式添加。

compile 'com.android.support:multidex:1.0.0'

如果您在应用程序中扩展了Application类:

  1. 请定义您的Application类继承MultiDexApplication类,例如:
public class MyApplication extends MultiDexApplication {
    ...
}

或者像@user2700475发布的那样

  1. 让您的应用程序重写attachBaseContext:
public class MyApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);}
}

在之前的回答的帮助下,我成功找到了解决这个问题的方法。我只是想把这一切整合起来。


谢谢,第一步很有帮助! - Sourav Chandra
我会推荐第三个选项,但是如果你使用Robolectric,那么单元测试可能会失败。 我在这里回答了类似的问题(https://dev59.com/RZjga4cB1Zd3GeqPIVBd),并提供了一些额外的链接和信息来解决围绕Multidex的一些问题。 - P Kuijpers

6
如果您没有使用Application类,您可以将以下内容放置在代码中:
android:name="android.support.multidex.MultiDexApplication"

在 AndroidManifest.xml 文件中的 <application> 标签内添加:

如果你已经实现了 Application 类,@user2700475 和 @sirvon 的回答是最好的选择。

同时,你需要添加 Gradle 依赖:

compile 'com.android.support:multidex:1.0.0'

关于65k方法问题的更多信息: https://developer.android.com/tools/building/multidex.html

(注:此处为原文,无需翻译)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接