从我的Android应用程序中我收到一条奇怪的错误消息:NullPointerException(在最后一行代码中)。
public static Integer getDefaultCalendarId(Context context) {
String calendarInSettings = PrefsHelper.getDefaultCalendar(context);
Calendar calendar = PrefsHelper.getCalendarFromPrefKey(context, calendarInSettings);
if (calendar == null || !calendar.canEventEdit()) {
return calculateDefaultCalendar(context);
}
boolean isChecked = false;
for (Calendar checkedCalendar : PrefsHelper.getCheckedCalendars(context)) {
if (checkedCalendar.getId() == calendar.getId()) {
isChecked = true;
break;
}
}
(1114 line) return isChecked ? calendar.getId() : calculateDefaultCalendar(context); // NullPointerException
}
Samsung GT-N7000发生异常。
这怎么可能发生?
更新
calculateDefaultCalendar可以返回null,但getDefaultCalendarId返回值 - 整数(可为空)!
堆栈跟踪:
java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx.trial/xxx.view.EventEditActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
at android.app.ActivityThread.access$600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at xxx.EventHelper.java.lang.Integer getDefaultCalendarId(android.content.Context)(SourceFile:1114)
at xxx.view.EventEditActivity.void onCreate(android.os.Bundle)(SourceFile:306)
at android.app.Activity.performCreate(Activity.java:4470)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
... 11 more
java.lang.NullPointerException
at xxx.EventHelper.java.lang.Integer getDefaultCalendarId(android.content.Context)(SourceFile:1114)
at xxx.view.EventEditActivity.void onCreate(android.os.Bundle)(SourceFile:306)
at android.app.Activity.performCreate(Activity.java:4470)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
at android.app.ActivityThread.access$600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
at dalvik.system.NativeStart.main(Native Method)
更新2
calculateDefaultCalendar:
private static Integer calculateDefaultCalendar(final Context context) {
String account = PrefsHelper.getAccountName(context);
if (account != null) {
for (Calendar calendar : PrefsHelper.getCheckedCalendars(context)) {
if (calendar.getOwnerAccount().equals(account) && calendar.canEventEdit()) {
return calendar.getId();
}
}
}
for (Calendar calendar : PrefsHelper.getCheckedCalendars(context)) {
if (calendar.canEventEdit()) {
return calendar.getId();
}
}
return null;
}
更新3
错误会定期重复:
产品/ android版
LT26i_1257-3921 / 4.0.4
MK16i_1249-8137 / 4.0.4
SCH-I500 / 2.3.5
SCH-I500 / 4.0.4
答案 0 :(得分:3)
return isChecked ? calendar.getId() : calculateDefaultCalendar(context);
我怀疑calendar.getId()
返回int
而不是Integer
。这意味着返回calculateDefaultCalendar(context)
的{{1}}首先需要自动取消装箱到Integer
,并且生成的int
必须自动装箱到int
1}}。如果Integer
为false且isChecked
返回calculateDefaultCalendar(context)
,则会产生null
。请参阅以下简化的等效代码,例如:
NPE
搜索相关字词class N2 {
public static void main(String args[])
{
System.out.println(check());
}
static Integer check()
{
return false ? 0 : fNull();
}
static Integer fNull()
{
return null;
}
}
,auto-boxing
和NullPointerException
会带来许多类似的热点。
答案 1 :(得分:1)
如果calender.getId()
返回int
,则会遇到自动装箱问题。由于最可能的罪魁祸首是calculateDefaultCalendar()
的返回值,因此编译器很可能尝试自动取消装箱null
返回值。要解决此问题,您只需使用calender.getId()
手动设置Integer.valueOf(calendar.getId())
的返回值即可。这样可以确保将返回的值设置为Integer
,然后calculateDefaultCalendar()
的返回值不会自动取消装箱。
答案 2 :(得分:0)
陈述显而易见的,其中一个是空的:
(已取消,之前在代码中成功调用)calendar
从返回(已删除,之前在代码中成功调用)getId()
从calculateDefaultCalendar
(已取消,之前在代码中成功调用)context
看起来calculateDefaultCalendar
由于某种原因返回null。在我们可以提供帮助之前,我们需要代码。
好的,既然我们已经calculateDefaultCalendar
,我们可以继续消除。从你的评论看,问题是这两个条件语句
if (calendar.getOwnerAccount().equals(account) && calendar.canEventEdit()) {
return calendar.getId();
}
和
if (calendar.canEventEdit()) {
return calendar.getId();
}
没有评估true
(否则他们会返回一个整数,你说)。所以,接下来要做的就是确保
account
不为空canEventEdit()
是真的通常,NPE跟踪就像这样,很容易。只需在代码中向后工作,直到某些内容发出NULL
,这就是源代码。