forceStop流程会把对应进程的pendingIntent给cancel掉
首先对比Android U和Android V的代码在forceStop时候的处理
Android U
@GuardedBy("this")final boolean forceStopPackageLocked(String packageName, int appId,boolean callerWillRestart, boolean purgeCache, boolean doit,boolean evenPersistent, boolean uninstalling, int userId, String reasonString,int reason) {...if (packageName == null || uninstalling) {didSomething |= mPendingIntentController.removePendingIntentsForPackage(packageName, userId, appId, doit);}....return didSomething;}
Android V
@GuardedBy("this")
final boolean forceStopPackageLocked(String packageName, int appId,boolean callerWillRestart, boolean purgeCache, boolean doit,boolean evenPersistent, boolean uninstalling, boolean packageStateStopped,int userId, String reasonString, int reason) {....boolean clearPendingIntentsForStoppedApp = false;try {// stop情况下,clearPendingIntentsForStoppedApp 为trueclearPendingIntentsForStoppedApp = (packageStateStopped&& android.content.pm.Flags.stayStopped());} catch (IllegalStateException e) {// It's unlikely for a package to be force-stopped early in the boot cycle. So, if we// check for 'packageStateStopped' which should evaluate to 'false', then this should// ensure we are not accessing the flag early in the boot cycle. As an additional// safety measure, catch the exception and ignore to avoid causing a device restart.clearPendingIntentsForStoppedApp = false;}if (packageName == null || uninstalling || clearPendingIntentsForStoppedApp) {final int cancelReason;if (packageName == null) {cancelReason = PendingIntentRecord.CANCEL_REASON_USER_STOPPED;} else if (uninstalling) {cancelReason = PendingIntentRecord.CANCEL_REASON_OWNER_UNINSTALLED;} else {cancelReason = PendingIntentRecord.CANCEL_REASON_OWNER_FORCE_STOPPED;}didSomething |= mPendingIntentController.removePendingIntentsForPackage(packageName, userId, appId, doit, cancelReason);}....return didSomething;
}
可以看到Androidv相比于Androidu,多了一个 clearPendingIntentsForStoppedApp,即在应用被forceStop的时候,也会移除对应的pendingIntent
对应的堆栈调用链
并且会移除alarmManager中的PendingIntent
private void makeIntentSenderCanceled(PendingIntentRecord rec,@CancellationReason int cancelReason) {rec.canceled = true;rec.cancelReason = cancelReason;final RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();if (callbacks != null) {final Message m = PooledLambda.obtainMessage(PendingIntentController::handlePendingIntentCancelled, this, callbacks);mH.sendMessage(m);}final AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);ami.remove(new PendingIntent(rec));}
根据PendingIntent的使用场景,可能会出现以下问题:
1.脑钟应用进程再被forceStop之后,如果用户不再去打开闹钟,那么闹钟到点不会响铃
2.音乐类应用传入meidaButton中的pendingIntent失效,导致应用进程被杀之后,无法通过耳机拉起音乐进程