以上是Android系统广播的流程,从Android13起逻辑上有变更,主要是对Android开机广播做了特殊处理。
if (Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(r.intent.getAction())) {
// Create one BroadcastRecord for each UID that can be deferred.
final SparseArray<BroadcastRecord> deferred =
r.splitDeferredBootCompletedBroadcastLocked(mQueue.mService.mInternal,
mQueue.mService.mConstants.mDeferBootCompletedBroadcast);
getDeferredPerUser(r.userId).enqueueBootCompletedBroadcasts(
Intent.ACTION_LOCKED_BOOT_COMPLETED, deferred);
if (!r.receivers.isEmpty()) {
// The non-deferred receivers.
mOrderedBroadcasts.add(r);
return;
}
} else if (Intent.ACTION_BOOT_COMPLETED.equals(r.intent.getAction())) {
// Create one BroadcastRecord for each UID that can be deferred.
final SparseArray<BroadcastRecord> deferred =
r.splitDeferredBootCompletedBroadcastLocked(mQueue.mService.mInternal,
mQueue.mService.mConstants.mDeferBootCompletedBroadcast);
getDeferredPerUser(r.userId).enqueueBootCompletedBroadcasts(
Intent.ACTION_BOOT_COMPLETED, deferred);
if (!r.receivers.isEmpty()) {
// The non-deferred receivers.
mOrderedBroadcasts.add(r);
return;
}
} else {
mOrderedBroadcasts.add(r);
}
}
其中很关键的代码,在特定场景会使用某些开机广播注册者无法收到开机广播:
final SparseArray deferred =
r.splitDeferredBootCompletedBroadcastLocked(mQueue.mService.mInternal,
mQueue.mService.mConstants.mDeferBootCompletedBroadcast);
getDeferredPerUser(r.userId).enqueueBootCompletedBroadcasts(
Intent.ACTION_BOOT_COMPLETED, deferred);
追踪mDeferBootCompletedBroadcast可知默认情况下后台及targetSdkVersion is T的开机广播接收者将会归为延时接收。
BroadcastDisppatcher中新增一个DeferredBootCompletedBroadcastPerUser,管理延时LOCKED_BOOT_COMPLETED,BOOT_COMPLETED的接收者。对于一个第三方应用中注册的开机广播往往会有这里做特殊处理,存放在SparseArray mDeferredBootCompletedBroadcasts = new SparseArray<>(),后续也是从此取出。