【发布时间】:2012-01-17 13:54:00
【问题描述】:
我有一个后台服务,它设置一个重复的警报,完成它的任务并自行停止。然后,当闹钟唤醒时,它会再次启动服务。如果程序崩溃,警报仍然存在并唤醒警报广播接收器。有没有办法在崩溃时取消警报 - 我想我可以从任何捕获的异常中取消警报,但其他原因呢?
或者当警报广播接收器被触发时,有什么方法可以判断设置它的程序是否崩溃了?
【问题讨论】:
标签: android
我有一个后台服务,它设置一个重复的警报,完成它的任务并自行停止。然后,当闹钟唤醒时,它会再次启动服务。如果程序崩溃,警报仍然存在并唤醒警报广播接收器。有没有办法在崩溃时取消警报 - 我想我可以从任何捕获的异常中取消警报,但其他原因呢?
或者当警报广播接收器被触发时,有什么方法可以判断设置它的程序是否崩溃了?
【问题讨论】:
标签: android
活动生命周期可以通过使用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();
}
然后广播接收器将使用我们之前添加的相同代码来检测服务或活动是否崩溃。
【讨论】: