我有一个后台服务,它设置重复警报,完成任务并停止自己。然后当警报唤醒时,它再次启动服务。如果程序崩溃,警报仍然存在并唤醒警报广播接收器。是否有任何方法可以在崩溃时取消警报 - 我想我可以从任何捕获的异常中取消警报但是其他原因呢?
或者当触发警报广播接收器时,有没有办法判断设置它的程序是否已经崩溃?
答案 0 :(得分:3)
活动生命周期可以通过在onDestroy()回调中使用 isFinishing()函数来检测“意外”终止的干净完成。您可以将其添加到应用中的每个活动:
protected void onDestroy () {
boolean crashedOnLastClose = false;
if (!isFinishing()) {
// The application is being destroyed by the O/S
crashedOnLastClose = true;
// Store the result somewhere for the BroadcastReceiver to check later
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("crashedOnLastClose", crashedOnLastClose);
editor.commit();
}
}
然后在您的BroadcastReceiver中,将结果从SharedPreferences框架(或您决定存储它的任何位置)拉回来,如果值为true,则取消操作:
public class MyAlarmReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean crashedOnLastClose = settings.getBoolean("crashedOnLastClose", false);
if (!crashedOnLastClose) {
// No crash on last run, handle the alarm
// ...
}
}
}
请记住在下次发布时将其重置为false!这样的事情应该做:
protected void onCreate (Bundle savedInstanceState) {
// Make sure this always resets to FALSE on launch
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("crashedOnLastClose", false);
editor.commit();
}
这应该捕获你的崩溃事件;但请记住,当您的应用程序强行关闭时,它也会检测到其他时间 - 例如设备上的内存不足。要区分这些类型的事件,您需要检查系统状态以及 isFinishing()。
编辑 - 服务
您的服务有一个单独的生命周期,您必须将其视为一个单独的应用程序。正如你所注意到的,这里没有“isFinishing()”,但是服务实际上非常简单,因为它们只能被你的代码干净地终止,你可以很容易地捕获它们。
在您的服务中,添加一个新的布尔值(可能称为“isFinishing”),并在服务结束时将其设置为true。然后重写onDestroy()并添加类似于我为您的活动描述的检查:
protected void onDestroy () {
// Store the result somewhere for the BroadcastReceiver to check later
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("crashedOnLastClose", !isFinishing);
editor.commit();
}
广播接收器将使用我们之前添加的相同代码来检测服务或活动是否崩溃。