Android 活动被销毁时服务中的空指针异常

Android 活动被销毁时服务中的空指针异常,android,android-service,android-broadcast,Android,Android Service,Android Broadcast,我有一个广播接收器,它根据PendingEvent调用服务。当“活动”处于“暂停”状态时,该服务工作正常,但当调用应用程序的onDestroy时,该服务将提供空指针 基本活动-- @Override protected void onPause() { super.onPause(); isResume = false; isPutToBackground = true; isDataPutToBackground = true; setNotificat

我有一个广播接收器,它根据PendingEvent调用服务。当“活动”处于“暂停”状态时,该服务工作正常,但当调用应用程序的onDestroy时,该服务将提供空指针

基本活动--

@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());

        }
    }
日志-


我怀疑问题在于此代码出现在onDestroy中,而onDestroy通常是为UI清理保留的,因此上下文对象将不可靠。请尝试将此代码移到桌面上

作为参考,这是Android活动生命周期。

来源:

我想在完成本地清理后,您应该调用super.ondestory:

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

我建议你把代码放到另一个地方。 从官方网站:

注意:不要指望调用此方法作为保存数据的位置!例如,如果活动正在编辑内容提供程序中的数据,则这些编辑应在onPause或onSaveInstanceStateBundle中提交,而不是在此处提交。此方法通常用于释放资源,如与活动关联的线程,以便在其应用程序的其余部分仍在运行时,已销毁的活动不会留下此类内容。在某些情况下,系统会简单地终止活动的宿主进程,而不调用此方法或其中的任何其他方法,因此不应使用此方法来执行希望在进程结束后保留的操作

派生类必须调用该方法的超类实现。如果没有,将抛出异常。

这是完整的日志类别吗?y,请扩展日志类别…它几乎是完整的日志。不清楚此日志中的错误发生在哪里…onDestroy代码在哪里?您可以发布吗?您可以指出它崩溃的行吗?
@Override
protected void onDestroy() {
    if (!isResume) {
        isResume = false;
        isPutToBackground = true;
        isDataPutToBackground = true;
        setNotification(_instance, true);
    }
    super.onDestroy();
}