低于Android Lollipop版本的java.lang.NoClassDefFoundError错误

6
我有一台安装了Android 21系统的Nexus 5设备。我在该设备上测试我的项目,没有问题。但是,如果我在带有Google APIs 19的模拟器上进行测试,则会显示错误java.lang.NoClassDefFoundError。如果它在Lollipop上运行良好,为什么会出现这个错误?我甚至问了我的朋友,他使用的是Sony 4.4设备,结果也崩溃了。我的编译SDK版本为21,构建工具设置为21.1.2。我尝试了gradle clean,我正在使用Android Studio。非常感谢您提供任何帮助。

此错误仅在低于Lollipop的设备上发生:

以下是Logcat中出现的内容:

02-10 07:46:19.200    2238-2238/com.myproject.android.indonesia E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.myproject.android.indonesia, PID: 2238
    java.lang.NoClassDefFoundError: com.myproject.android.indonesia.task.GetProjectTask$1
            at com.myproject.android.indonesia.task.GetProjectTask.execute(GetProjectTask.java:27)
            at com.myproject.android.indonesia.activity.SplashActivity.launchProjectTask(SplashActivity.java:111)
            at com.myproject.android.indonesia.activity.SplashActivity.onCreate(SplashActivity.java:71)
            at android.app.Activity.performCreate(Activity.java:5231)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)

这里是调用getProjectTask()函数的片段。
GetProjectTask mGetProjectTask = new GetProjectTask(this);
mGetProjectTask.mUrl.append(Constants.Link.HOST).append(Constants.Webservice.GET_PROJECT);
mGetProjectTask.params.put(Constants.Key.PRJ_LICENCE, Constants.Constant.LICENCE);
mGetProjectTask.params.put(Constants.Key.LANGUAGE, currentLanguage);
mGetProjectTask.params.put(Constants.Key.CTY_NAME, Constants.Value.APP_CTY_NAME);
mGetProjectTask.execute();

更新 看起来我需要使用我正在使用的SDK中的最新版本才能避免这个错误(Aviary SDK)。当我升级后,这个错误就不再出现了。


1
请发布完整的堆栈跟踪 - CommonsWare
1
你能展示一下这行代码所在的代码片段吗?它在 SplashActivity.java 文件的第 71 行。还有 GetProjectTask 函数的代码片段吗? - hrskrs
getProjectTask 在我的 onCreate 方法中被调用。请参见上面的代码片段。 - SleepNot
2
你需要发布 GetProjectTask 的代码,因为它使用了一些仅在 Lollipop 中出现的新类。你的应用程序能够在 Lollipop 上运行并不意味着它可以运行在旧的系统上... - darnmason
1
你能发布一下 GetProjectTask 的代码吗? - Juampa
显示剩余3条评论
3个回答

5
你的类(在GetProjectTask中的第一个匿名类)继承了一个在该平台上不可用的类。

但在将我们项目的目标设置为Android 21之前,该应用程序可以支持4.0+版本。只是因为一个库需要21才能构建,这使得该应用程序仅可在5.0中运行。我的最低SDK版本设置为17。 - SleepNot
1
如果你有一个需要API 21的库,那么你不能在低于API 21的设备上使用它(包括其类)。 - StenSoft

1
如果仔细查看API文档,您会注意到在类文档的右上角和每个API方法中都有“添加于API x”的文本。
例如参见AnimatedVectorDrawable - 它是在API级别21(棒棒糖)添加的。
在旧设备上尝试使用添加于API 21的类将失败,并出现异常。这并不奇怪,因为不幸的是旧操作系统版本中没有新功能。
您可以通过几种方式克服此异常:使用兼容性库、仅在手机支持时启用新功能(通过检查Build.Version.SDK_INT或使用api级别特定的res文件夹,例如layout-v21)。
另一种选择是将minSdkVersion设置为21,然后您的应用程序将拒绝在旧设备上安装(并且不会出现在其 Google Play 店中)。
有关此主题的更多详细信息,请参见Android文档上compatibility

请纠正我,但我理解使用兼容性库(appcompat)可以解决这个问题。这不总是正确的吗? - SleepNot
你错了。Appcompat并不是魔法,它只是实现了一些功能,并且与你的应用程序捆绑在一起(使你的APK变得更大)。有时候可能行(实现片段、简单动画),但一些新功能需要更强的硬件(阴影、模糊),或者更深层次的操作系统改变(矢量动画使用特殊的操作系统“渲染线程”)。 - Iftah
还要注意,AppCompat中的类与android.app.Fragment不是同一个类,后者使用操作系统级别实现的Fragment,而android.support.v4.app.Fragment在您的apk中实现了类似的逻辑。即使它们对使用它们的程序员来说看起来相同,由于Java是强类型语言,它们也不能互换。 - Iftah

0

这对我有用,需要在build.gradle中添加:

 dexOptions {
        preDexLibraries = false
        javaMaxHeapSize = "4g"
    }

编译 'javax.inject:javax.inject:1' 在应用程序类中扩展 MultiDexApplication
不要覆盖 attachBaseContext 方法。

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