1

从我的 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
}

三星 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

计算默认日历:

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

错误定期重复:

产品/安卓版本

LT26i_1257-3921 / 4.0.4

MK16i_1249-8137 / 4.0.4

SCH-I500 / 2.3.5

SCH-I500 / 4.0.4

4

3 回答 3

3
return isChecked ? calendar.getId() : calculateDefaultCalendar(context);

我怀疑calendar.getId()退货intInteger。这意味着calculateDefaultCalendar(context)返回 a 的Integer,首先需要自动拆箱,int结果int必须自动装箱到Integer。如果isChecked为 false 并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-boxingNullPointerExceptionternary带来许多类似的热点。

于 2012-12-04T01:50:55.860 回答
1

如果calender.getId()返回一个int,您将遇到自动装箱问题。由于最可能的罪魁祸首是 的返回值calculateDefaultCalendar(),因此编译器很可能试图自动拆箱null返回值。calender.getId()要解决此问题,您可以简单地手动将with的返回值装箱Integer.valueOf(calendar.getId())。这将确保返回值被装箱为 anInteger然后返回值calculateDefaultCalendar()不会被自动拆箱。

于 2012-12-04T02:08:13.033 回答
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内容,这就是源代码。

于 2012-11-23T08:04:45.153 回答