局部变量变为null(Android)

时间:2012-11-23 07:59:08

标签: java android exception nullpointerexception

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

3 个答案:

答案 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-boxingNullPointerException会带来许多类似的热点。

答案 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,这就是源代码。