Android应用被浅杀和深杀

浅杀:

04-21 17:55:13.733 8264-8264/com.qintong.test D/qintong: vCardService onTaskRemoved.

深杀:

会出现两种情况:

(a).

04-26 16:20:00.349 32674-32674/? D/qintong: Service onTaskRemoved.

04-26 16:21:01.621 2936-2936/? D/qintong: Service is being created.

04-26 16:21:01.628 2936-2936/? D/qintong: Service onStartCommand.

(b).

04-21 17:59:58.397 8264-8264/com.qintong.test D/qintong: Service onCreate.

04-21 17:59:58.404 8264-8264/com.qintong.test D/qintong: Service onTaskRemoved.

浅杀+深杀 (service 的 onStartCommand 返回 STICKY):

04-21 18:05:12.717 8264-8264/com.qintong.test D/qintong: Service onTaskRemoved.

04-21 18:05:29.214 9207-9207/com.qintong.test D/qintong: Service onCreate.

04-21 18:05:29.223 9207-9207/com.qintong.test D/qintong: Service onStartCommand.

我们来分析这几种情况:

(1).浅杀时:应用进程没被杀掉,service仍然在执行,service的onTaskRemoved()立即被调用。

(2).深杀时:有两种情况:第一种情况是深杀后直接调用onTaskRemoved()且service停止,过段时间后service重启调用其onCreate()和onStartCommand()。第二种是应用的进程被杀掉,过一会后service的onCreate()方法被调用,紧接着onTaskRemoved()被调用。由于被深杀后应用的进程立刻停止了,所以service的onTaskRemoved()无法被立即调用。而过若干秒后,service重启,onCreate()被调用,紧接着onTaskRemoved()被调用。而这里service的其他方法并没有被调用,即使onStartCommand()返回STICKY,service重启后onStartCommand()方法也没有被调用。

(3).浅杀+深杀时(service 的 onStartCommand 返回 STICKY):onTaskRemoved()立刻被调用(浅杀后),深杀后过段时间onCreate()和onStartCommand()相继被调用。执行浅杀Task被清理,应用的进程还在,onTaskRemoved()被调用,过程与(1)一样。再执行深杀:由于该应用的Task栈已经没有了,所有再深杀onTaskRemoved()不会再被调用,深杀后service停止。而由于实验时候onStartCommand()返回STICKY,所有service过段时间会被再次启动,执行了onCreate()方法和onStartCommand()方法。

所以综上所述,service的onTaskRemoved()在应用浅杀后会被立即调用而在service被深杀后,会直接调用onTaskRemoved或service会被重启并调用onTaskRemoved()。

回到我们的问题:应用被杀后,如何取消Notification:

我们先看最后的解决方案,在来分析为何能work。

service的代码如下:

@Override

public void onCreate() {

super.onCreate();

mBinder=newMyBinder();

if(DEBUG) Log.d(LOG_TAG,"vCardService is being created.");

mNotificationManager= ((NotificationManager)getSystemService(NOTIFICATION_SERVICE));

initExporterParams();

}

@Override

public int onStartCommand(Intent intent, intflags, intid) {

if(DEBUG) Log.d(LOG_TAG,"vCardService onStartCommand.");

mNotificationManager.cancelAll();

returnSTART_STICKY;

}

@Override

public void onTaskRemoved(Intent rootIntent) {

if(DEBUG) Log.d(LOG_TAG,"vCardService onTaskRemoved.");

mNotificationManager.cancelAll();

super.onTaskRemoved(rootIntent);

}

如上代码,在浅杀时候:只执行onTaskRemoved(),通知被取消,但service仍然在运行,所以还会继续发通知,正常运行。

深杀时:第一种情况直接调用onTaskRemoved()且service停止,通知被取消。第二种情况,进程被杀掉,几秒后service重启,onCreate() -> onTaskRemoved(),运行结果就是深杀后过几秒后Notification被取消。

浅杀+深杀时:浅杀后onTaskRemoved()被调用,service仍在运行,通知仍然在更新。深杀时,onCreate() -> onStartCommand(),在onStartCommand()时候取消通知。

另外,mNotificationManager.cancelAll()会清除应用的所有通知,如果应用想保留和该service无关其他通知,可以调用mNotificationManager.cancel(String tag, int id)或cancel(int id)清除指定通知。

当然,还可以有另一种方式:浅杀时后就把service后台执行的任务停止,并清理notification,我们可以根据需求来选择。