在Android应用中调用静态方法时出现致命异常:java.lang.NoClassDefFoundError

7

我们的一位测试人员在使用运行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添加的库中。我所提到的问题崩溃来自于我的自己的库项目代码部分,而且同样的静态方法调用在 App 的其他地方也能正常工作。这个问题似乎正在扩散,或者至少不仅局限于1个类或1个库。

我们在 build.gradle 中针对以下 Android 版本进行开发:

minSdkVersion 14
targetSdkVersion 22  (android 5.1)

这里可能发生了什么事情?还有一件需要注意的事情是,签名的APK是使用Android Studio 2.0 preview 4生成的。然而,该应用程序对其他20-30个测试人员正常运行,因此我不想指责使用Studio的预览版本。


"1.) "$5"在类名后面是什么意思?" MyCustomClass$5 是在 MyCustomClass 中定义的匿名类的名称。它不一定是该类源代码中出现的第5个匿名类,但很可能至少有5个匿名类在其中。 - Andy Turner
@AndyTurner 我猜测是在“getNumberOfItems”方法内部的CollectionUtils.filter调用。我现在会更新我的问题,并附上该方法的代码。 - DiscDev
2
这里有一个可能与multidex设置不正确有关的原因:https://dev59.com/Hl4c5IYBdhLWcg3wn7qj。不确定您是否在使用它,但检查一下可能是值得的。 - George Mulligan
@GeorgeMulligan 你可能有所发现。真的很好的发现!如果有帮助,我会回报的。 - DiscDev
你启用了Proguard吗?如果是,请将你的proguard-rules.pro放在它的上方。 - Rod_Algonquin
@GeorgeMulligan 你是对的!谢谢!!! - DiscDev
2个回答

8
这些NoClassDefFoundError的出现是因为该应用程序中只部分实现了multidex - 由于某种原因,这在Android 5/6上运行良好,但在Android 4.x上会导致您的应用程序在随机位置崩溃并显示NoClassDefFoundError。我认为Android Studio应该检测到这种情况,并警告您未正确实现multidex支持。
要解决此问题,请确保对您的项目满足以下条件:
1.在应用程序级build.gradle的defaultConfig部分中设置multiDexEnabled = true 2.在项目级build.gradle中添加compile 'com.android.support:multidex:1.0.0' 3.在Application类的attachBaseContext()中调用MultiDex.install() 有关multidex的更多详细信息,请单击此处

6
我已经在我的项目中添加了上述三点。仍然出现相同的错误。而且这个错误出现在Android 6操作系统上。 - Rameshbabu
1
和我一样,已经尝试了上述方法,但仍然显示错误。我担心这是由于通过 Playstore 以外的方式安装的 AAB 文件引起的?这是否与 GloballyDynamic 工具 有关? - mochadwi

0

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

对于多 dex 应用程序构建每个 DEX 文件时,构建工具执行复杂的决策,以确定哪些类需要包含在主 DEX 文件中,以便您的应用程序可以成功启动。如果在启动期间需要的任何类未在主 DEX 文件中提供,则您的应用程序将崩溃,并显示 java.lang.NoClassDefFoundError 错误。

using proguard

编辑:

或者您可以尝试这种方法,将您的类注册在主要的DEX中,以便更加方便地使用。

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


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