当活动被销毁时,来自Service的空指针异常

时间:2014-08-28 10:27:08

标签: android android-service android-broadcast

我有一个广播接收器,它根据pendingIntent调用服务。当活动处于onPause状态时,该服务正常工作,但是当调用应用程序的onDestroy时,服务正在提供NullPointer。

BaseActivity ---

@Override
protected void onPause() {
    super.onPause();
    isResume = false;
    isPutToBackground = true;
    isDataPutToBackground = true;
    setNotification(_instance, false);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (!isResume) {
        isResume = false;
        isPutToBackground = true;
        isDataPutToBackground = true;
        setNotification(_instance, true);
    }}

    public static void setNotification(Context ctx, boolean isDestroyed) {
    cancelNotification(_instance);
    myIntent = new Intent(ctx, NotificationReceiver.class);
    dataIntent = new Intent(ctx, NotificationReceiver.class);

    if (!Prefs.getInstance().isLoggedIn) {
        createDailyReminder(ctx, false, false, isDestroyed);
    } else {
        if (Prefs.getInstance().isDataReminder) {
            createWeeklyReminder(ctx, isDestroyed);

        }
        if (Prefs.getInstance().reminderInterval.equals("1 Day")|| Prefs.getInstance().reminderInterval.equals("")) {
            createDailyReminder(ctx, true, false, isDestroyed);
        } else {
            createDailyReminder(ctx, true, true, isDestroyed);
        }
    }

}

public static void cancelNotification(Context ctx) {
Intent myIntent = new Intent(ctx, NotificationReceiver.class);
Intent dataIntent = new Intent(ctx, NotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(ctx, 11122, myIntent, 0);
dataPendingIntent = PendingIntent.getBroadcast(ctx, 11133, dataIntent,0);
dataPendingIntent.cancel();
pendingIntent.cancel();
alreadyBackrogund = false;
dataAlreadyBackrogund = false;
}

private static void createWeeklyReminder(Context ctx, boolean isDestroyed) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(ALARM_SERVICE);
dataIntent.putExtra("DATA", true);
if (isDestroyed) {
dataIntent.putExtra("ISDESTROYED", true);
} else {
dataIntent.putExtra("ISDESTROYED", false);
}
dataPendingIntent = PendingIntent.getBroadcast(ctx, 11122, dataIntent,0);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),alarmManager.INTERVAL_DAY * 7, dataPendingIntent);

}

private static void createDailyReminder(Context ctx, boolean loggedIn,
        boolean isWeekly, boolean isDestroyed) {
    AlarmManager alarmManager = (AlarmManager) ctx
            .getSystemService(ALARM_SERVICE);
    if (loggedIn) {
        if (!isWeekly) {
            myIntent.putExtra("DATA", false);
            if (isDestroyed) {
                dataIntent.putExtra("ISDESTROYED", true);
            } else {
                dataIntent.putExtra("ISDESTROYED", false);
            }
            pendingIntent = PendingIntent.getBroadcast(ctx, 11133,
                    myIntent, 0);
            alarmManager.setRepeating(AlarmManager.RTC,
                    getFuture10AMData(2), AlarmManager.INTERVAL_DAY,
                    pendingIntent);
        } else {
            myIntent.putExtra("DATA", false);
            if (isDestroyed) {
                dataIntent.putExtra("ISDESTROYED", true);
            } else {
                dataIntent.putExtra("ISDESTROYED", false);
            }
            pendingIntent = PendingIntent.getBroadcast(ctx, 11133,
                    myIntent, 0);
            alarmManager.setRepeating(AlarmManager.RTC,
                    getFuture10AMData(8), AlarmManager.INTERVAL_DAY,
                    pendingIntent);
        }

    } else {
        myIntent.putExtra("DATA", false);
        if (isDestroyed) {
            dataIntent.putExtra("ISDESTROYED", true);
        } else {
            dataIntent.putExtra("ISDESTROYED", false);
        }
        pendingIntent = PendingIntent.getBroadcast(ctx, 11133, myIntent, 0);
        alarmManager.setRepeating(AlarmManager.RTC, getFuture10AMData(1),
                AlarmManager.INTERVAL_DAY, pendingIntent);
    }

}

private static long getFuture10AMData(int count) {
    Calendar calendar = Calendar.getInstance();
    // Date today = calendar.getTime();

    calendar.add(Calendar.DAY_OF_YEAR, count);
    // Date tomorrow = calendar.getTime();
    calendar.set(Calendar.HOUR_OF_DAY, 10);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.AM_PM, Calendar.AM);

    return calendar.getTimeInMillis();

}

广播接收器

    @Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub

    boolean isDataReminder = intent.getBooleanExtra("DATA", false);
    boolean isDestroyed = intent.getBooleanExtra("ISDESTROYED", false);

    Intent dataNotificationService = new Intent(context,
            DataNotificationService.class);
    Intent notificationService = new Intent(context,
            NotificationService.class);
    if (isDataReminder) {
        dataNotificationService.putExtra("ISDESTROYED", isDestroyed);
        context.startService(dataNotificationService);
    } else {
        notificationService.putExtra("ISDESTROYED", isDestroyed);
        context.startService(notificationService);
    }

}

服务代码----

    public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);

        Prefs.getInstance().loadPrefs(getApplicationContext());
        Log.i("MBB APP", "Data Service called");
        boolean isDestroyed = intent.getBooleanExtra("ISDESTROYED", false);
        System.out.println("Data Service Booleans"
                + BaseActivity.dataAlreadyBackrogund + ","
                + BaseActivity.isDataPutToBackground
                + "  ISDestroyed boolean " + isDestroyed);
        try {
            if (BaseActivity.dataAlreadyBackrogund
                    && BaseActivity.isDataPutToBackground) {
                if (BaseActivity.isDataPutToBackground
                        && Prefs.getInstance().isLoggedIn) {
                    generateDataNotification(
                            getApplicationContext(),
                            "You have created "
                                    + Prefs.getInstance().noOfQuotes
                                    + " and saved "
                                    + Prefs.getInstance().noOfLeads
                                    + " using MBB"
                                    + "\n"
                                    + "You last Quoted with MBB on "
                                    + Prefs.getInstance().lastQuoteTimeStamp
                                    + "\n"
                                    + "You last saved Lead with MBB on "
                                    + Prefs.getInstance().lastLeadTimeStamp
                                    + "\n"
                                    + "Add to your book of business now");

                }
            } else {
                BaseActivity.dataAlreadyBackrogund = true;
                // Prefs.getInstance().savePrefs(getApplicationContext());
            }
        } catch (Exception e) {
            Log.e("MBB Service Exception", e.toString());

        }
    }

记录----

09-03 15:42:04.008: E/AndroidRuntime(10701): FATAL EXCEPTION: main
09-03 15:42:04.008: E/AndroidRuntime(10701): java.lang.RuntimeException: Unable to start service com.test..DataNotificationService@41d2d050 with null: java.lang.NullPointerException
09-03 15:42:04.008: E/AndroidRuntime(10701):    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2571)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at android.app.ActivityThread.access$2000(ActivityThread.java:140)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1334)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at android.os.Looper.loop(Looper.java:137)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at android.app.ActivityThread.main(ActivityThread.java:4921)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at java.lang.reflect.Method.invokeNative(Native Method)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at java.lang.reflect.Method.invoke(Method.java:511)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
09-03 15:42:04.008: E/AndroidRuntime(10701):    at dalvik.system.NativeStart.main(Native Method)

3 个答案:

答案 0 :(得分:3)

我怀疑问题是这个代码发生在onDestroy()中,通常是为UI清理保留的,因此Context对象不可靠。请尝试将此代码移至onStop()

供参考,这是Android Activity生命周期。 Activity Lifecycle

来源:http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

答案 1 :(得分:0)

我想你完成本地清理工作后应该致电super.onDestroy()

@Override
protected void onDestroy() {
    if (!isResume) {
        isResume = false;
        isPutToBackground = true;
        isDataPutToBackground = true;
        setNotification(_instance, true);
    }
    super.onDestroy();
}

答案 2 :(得分:0)

我建议您将代码放到其他地方。 来自官方网站:

注意:不要指望将此方法称为保存数据的地方!例如,如果某个活动正在编辑内容提供程序中的数据,那么这些编辑应该在onPause()或onSaveInstanceState(Bundle)中提交,而不是在此处。通常实现此方法是为了释放与活动相关联的线程之类的资源,以便在其应用程序的其余部分仍在运行时,被破坏的活动不会留下这些东西。在某些情况下,系统会在不调用此方法(或其他任何方法)的情况下简单地终止活动的托管过程,因此不应将其用于执行过程消失后要保留的内容。

派生类必须调用超类的此方法实现。如果他们不这样做,将抛出异常。 :http://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29