【问题标题】:Fatal Exception: java.lang.NoClassDefFoundError when calling static method in Android app致命异常:在 Android 应用中调用静态方法时出现 java.lang.NoClassDefFoundError
【发布时间】:2016-05-02 01:42:46
【问题描述】:

我们的一位 Beta 测试人员使用运行 Android 4.4.4 的 T-mobile Galaxy S4 遇到了非常奇怪的 NoClassDefFoundError 崩溃。我完全不知道为什么会发生这些。

最近一次发生在片段中的onCreateView 中调用静态方法时。

MyCustomClass.getNumberOfItems(getActivity());

失败

致命异常:java.lang.NoClassDefFoundError com.mycompany.myapp.utilities.MyCustomClass$5

这是有问题的方法:

public static List<Item> getNumberOfItems(final Context context)
{
    List<Item> allFinishedItems = getAllFinishedItems(context);

    CollectionUtils.filter(allFinishedItems, new Predicate<Item>()
    {
        @Override
        public boolean evaluate(Item item)
        {
            // TODO Auto-generated method stub
            return isNonCustomItem(context, item);
        }
    });

    return allFinishedItems;
}

1.) 类名后面的“$5”是什么? (答案:使用 CollectionUtils.filter 引用匿名类进行过滤) 2.) 该用户发生了另一次类似性质的崩溃,但使用了完全不同的静态方法调用,该方法调用位于通过 gradle 包含的库中。我在这个问题中引用的崩溃来自我自己的库项目中的代码,并且相同的静态方法调用在应用程序的其他地方也有效。这个问题似乎正在蔓延,或者至少不包含在 1 个类或 1 个库中。

我们在 build.gradle 中针对以下 Android 版本:

minSdkVersion 14
targetSdkVersion 22  (android 5.1)

这里可能发生了什么?另一件需要注意的事情是,签名的 APK 是使用 Android Studio 2.0 预览版 4 生成的。但是,该应用程序适用于 20-30 名其他 beta 测试人员,所以我不愿指责使用 Studio 的预览版。

【问题讨论】:

  • "1.) 类名后面的“$5”是什么? MyCustomClass$5 是在MyCustomClass 中定义的匿名类的名称。它不一定是该类的源代码中出现的第 5 个匿名类,但您可能至少有 5 个。
  • @AndyTurner 我猜这是“getNumberOfItems”方法中的 CollectionUtils.filter 调用。我现在将使用该方法的代码更新我的问题。
  • 这是与 multidex 设置不正确相关的一个潜在原因 stackoverflow.com/questions/27698287/…。不确定您是否正在使用它,但可能值得一试。
  • @GeorgeMulligan 您可能正在做某事。真的很好找!如果有帮助,我会回来报告。
  • 你启用proguard了吗?如果是,请将您的proguard-rules.pro 放在上方

标签: java android android-gradle-plugin noclassdeffounderror


【解决方案1】:

NoClassDefFoundErrors 之所以发生,是因为 multidex 仅在此应用中部分实现 - 出于某种原因,这在 Android 5/6 上运行良好,但在 Android 4.x 上,它会使您的应用在随机位置出现 NoClassDefFoundError 崩溃.在我看来,Android Studio 应该会检测到这种情况,并且应该警告您您未正确实现 multidex 支持。

要修复它,请确保您的项目满足以下条件:

  1. multiDexEnabled = true 在应用级 build.gradle 的 defaultConfig 部分中

  2. compile 'com.android.support:multidex:1.0.0' 在您的项目级 build.gradle 中

  3. 在您的应用程序类的attachBaseContext() 中调用MultiDex.install()

更多关于multidex的详情可以查看here.

【讨论】:

  • 以上三点我已经在我的项目中添加了。仍然遇到同样的错误。 Android OS 6 中也有错误。
  • 和我一样,上面的方法已经添加了,但仍然显示错误。恐怕这是由于通过 Playstore 以外的方式安装的 AAB?和这个GloballyDynamic tools有关系吗
【解决方案2】:

确保按照其他人在此处指出的答案设置先决条件,如果仍然发生崩溃,您可能还想尝试这种方法https://developer.android.com/studio/build/multidex#keep

在为 multidex 应用程序构建每个 DEX 文件时,构建工具会执行复杂的决策,以确定主 DEX 文件中需要哪些类,以便您的应用程序能够成功启动。如果主 DEX 文件中未提供启动期间所需的任何类,则您的应用程序将崩溃并出现错误 java.lang.NoClassDefFoundError

编辑:

或者您可以尝试这种方法,以便在主 DEX 中注册您的类

https://medium.com/androidiots/androidiots-podcast-6-the-black-magic-behind-android-runtime-part-2-9390f751eef0

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    相关资源
    最近更新 更多