1、mIntentSenderRecords
是一个PendingIntentRecord哈希表。一个PendingIntentRecord对象对应的是应用层的一个PendingIntent对象(延迟性的intent),其中包含send系列方法,主要用于触发PendingIntent的Intent行为。上层应用每获取一个PendingIntent对象时在AMS这边便会生成对应的PendingIntentRecord对象,并保存在mIntentSenderRecords哈希列表中,当上层应用调用PendingIntent.send()时,最终会调用到PendingIntentRecord.sendInner()函数,这个函数会将之前上层应用传下来的Intent进行触发(起Activity、发广播、起service)。PendingIntent对象是可以传递给其他应用的,这个应该才是设计初衷?
2、mRegisteredReceivers
是一个ReceiverList哈希表。ReceiverList对应一个广播接收器,mRegisteredReceivers保存着系统中的所有广播接收器。ReceiverList继承于ArrayList<BroadcastFilter>,实质上就是一个BroadcastFilter列表,源码是这样解释ReceiverList的:
- <span style="font-size:14px;">**
- * A receiver object that has registered for one or more broadcasts.
- * The ArrayList holds BroadcastFilter objects.
- *</span>
- <span style="font-size:14px;">public Intent registerReceiver(IApplicationThread caller, String callerPackage,
- IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
- ...........
- ReceiverList rl = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
- if (rl == null) {
- rl = new ReceiverList(this, callerApp, callingPid, callingUid,
- userId, receiver);
- if (rl.app != null) {
- rl.app.receivers.add(rl);
- } else {
- try {
- receiver.asBinder().linkToDeath(rl, 0);
- } catch (RemoteException e) {
- return sticky;
- }
- rl.linkedToDeath = true;
- }
- mRegisteredReceivers.put(receiver.asBinder(), rl);
- }
- .............
- BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
- permission, callingUid, userId);
- rl.add(bf);
- mReceiverResolver.addFilter(bf);
- if (allSticky != null) {
- ArrayList receivers = new ArrayList();
- receivers.add(bf);
- int N = allSticky.size();
- for (int i=0; i<N; i++) {
- Intent intent = (Intent)allSticky.get(i);
- BroadcastQueue queue = broadcastQueueForIntent(intent);
- BroadcastRecord r = new BroadcastRecord(queue, intent, null,
- null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
- null, null, false, true, true, -1);
- queue.enqueueParallelBroadcastLocked(r);
- queue.scheduleBroadcastsLocked();
- }
- }
- return sticky;
- }
- }</span>
上面的代码可以看出一个广播接收器在AMS这边对应有一个ReceiverList,其实是一个BroadcastFilter列表,属于这个广播接受器的IntentFilter对应的BroadcastFilter对象保存在ReceiverList列表中。IntentFilter中的每个action,都会生成一个Intent,每个Intent又会对应new一个BroadcastRecord,然后根据这个Intent是否设置Intent.FLAG_RECEIVER_FOREGROUND来选择一个BroadcastQueue队列来将这个BroadcastRecord加入到队列中。有两个BroadcastQueue队列,分别是mFgBroadcastQueue和mBgBroadcastQueue。所有的BroadcastFilter会保存在mReceiverResolver(IntentResolver对象)中。
2、broadcastIntent()
发送广播处理函数。详情请看:博客
ContextImpl.sendBroadcastAsUser()-->AMS.broadcastIntent()-->AMS.broadcastIntentLocked(),broadcastIntentLocked()函数关键代码如下:
- <span style="font-size:14px;"> private final int broadcastIntentLocked(ProcessRecord callerApp,
- String callerPackage, Intent intent, String resolvedType,
- IIntentReceiver resultTo, int resultCode, String resultData,
- Bundle map, String requiredPermission, int appOp,
- boolean ordered, boolean sticky, int callingPid, int callingUid,
- int userId) {
- //①首先进行权限检查
- //②检查是否是特别广播,如ACTION_PACKAGE_REMOVED、ACTION_PACKAGE_ADDED、ACTION_TIMEZONE_CHANGED、ACTION_CLEAR_DNS_CACHE、PROXY_CHANGE_ACTION
- if (sticky) {
- //③粘性广播处理
- }
- // Figure out who all will receive this broadcast.
- List receivers = null;
- List<BroadcastFilter> registeredReceivers = null;
- // Need to resolve the intent to interested receivers...
- if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
- == 0) {
- receivers = collectReceiverComponents(intent, resolvedType, users); //③从PackageManagerService中收集静态注册的广播接收器;
- }
- if (intent.getComponent() == null) { //③如果广播没有指定组件,那么就从</span><span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif;">mReceiverResolver中进行queryIntent()匹配;</span><span style="font-size:14px;">
- registeredReceivers = mReceiverResolver.queryIntent(intent,
- resolvedType, false, userId);
- }
- final boolean replacePending =
- (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
- int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
- if (!ordered && NR > 0) {
- //④如果该广播是无序广播,并且存在动态注册的接收器,那么先将该广播(BroadcastRecord)加入到BroadcastQueue.mParallelBroadcasts中,注意此BroadcastRecord. Receivers只包含动态注册的接收器。
- // If we are not serializing this broadcast, then send the
- // registered receivers separately so they don't wait for the
- // components to be launched.
- final BroadcastQueue queue = broadcastQueueForIntent(intent); //④从mFgBroadcastQueue和mBgBroadcastQueue中挑一个广播队列(前台后台广播);
- BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
- appOp, registeredReceivers, resultTo, resultCode, resultData, map,
- ordered, sticky, false, userId);
- if (DEBUG_BROADCAST) Slog.v(
- TAG, "Enqueueing parallel broadcast " + r);
- final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
- if (!replaced) {
- queue.enqueueParallelBroadcastLocked(r); //④将</span><span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif;">BroadcastRecord加入广播队列,并启动发送;</span><span style="font-size:14px;">
- queue.scheduleBroadcastsLocked();
- }
- registeredReceivers = null;
- NR = 0;
- }
- // Merge into one list.
- int ir = 0;
- if (receivers != null) {
- //⑤对于有序广播,根据优先级合并动态注册、静态注册的广播接收器;对于无序广播,代码运行到此处必然只剩下静态注册广播接收器了,也会add到</span><span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif;">receivers列表中;</span><span style="font-size:14px;">
- int NT = receivers != null ? receivers.size() : 0;
- int it = 0;
- ResolveInfo curt = null;
- BroadcastFilter curr = null;
- while (it < NT && ir < NR) {
- if (curt == null) {
- curt = (ResolveInfo)receivers.get(it);
- }
- if (curr == null) {
- curr = registeredReceivers.get(ir);
- }
- if (curr.getPriority() >= curt.priority) {
- // Insert this broadcast record into the final list.
- receivers.add(it, curr);
- ir++;
- curr = null;
- it++;
- NT++;
- } else {
- // Skip to the next ResolveInfo in the final list.
- it++;
- curt = null;
- }
- }
- }
- while (ir < NR) {
- if (receivers == null) {
- receivers = new ArrayList();
- }
- receivers.add(registeredReceivers.get(ir));
- ir++;
- }
- //⑥如果是有序广播,将会合并动态注册、静态注册的接收器,然后将合并好的接收器list保存在BroadcastRecord.Receivers中,同时把BroadcastRecord加入到BroadcastQueue.mOrderedBroadcasts中
- //⑦如果是无序广播,存在静态注册的接收器,那么又会new BroadcastRecord,将静态注册的接收器保存在BroadcastRecord.Receivers中,同时把BroadcastRecord加入到BroadcastQueue.mOrderedBroadcasts中
- if ((receivers != null && receivers.size() > 0)
- || resultTo != null) {
- BroadcastQueue queue = broadcastQueueForIntent(intent);
- BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, resolvedType,
- requiredPermission, appOp, receivers, resultTo, resultCode,
- resultData, map, ordered, sticky, false, userId);
- if (DEBUG_BROADCAST) Slog.v(
- TAG, "Enqueueing ordered broadcast " + r
- + ": prev had " + queue.mOrderedBroadcasts.size());
- if (DEBUG_BROADCAST) {
- int seq = r.intent.getIntExtra("seq", -1);
- Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
- }
- boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
- if (!replaced) {
- queue.enqueueOrderedBroadcastLocked(r);
- queue.scheduleBroadcastsLocked();
- }
- }
- return ActivityManager.BROADCAST_SUCCESS;
- }
- </span>
在第①条中提到当注册一个广播接收器时,会将BroadcastFilter保存在mReceiverResolver(IntentResolver对象)中,何种方式保存的呢?就是以BroadcastFilter和action成对地保存在mReceiverResolver.mActionToFilter中。这段代码的逻辑是①通过queryIntent()从mReceiverResolver.mActionToFilter中根据action找出所有的BroadcastFilter;②选取一个合适的BroadcastQueue;③new一个BroadcastRecord,将①②两步获取的对象都作为参数保存到BroadcastRecord中;④将BroadcastRecord加入到合适的BroadcastQueue队列中,其实就是加入到一个待发送广播list中;⑥启动将广播发送给对应Receiver流程(scheduleBroadcastsLocked())。
总结:
- <span style="font-size:14px;"> public void scheduleBroadcastsLocked() {
- if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
- + mQueueName + "]: current="
- + mBroadcastsScheduled);
- if (mBroadcastsScheduled) {
- return;
- }
- mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
- mBroadcastsScheduled = true;
- }
- </span>
- <span style="font-size:14px;"> final Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case BROADCAST_INTENT_MSG: {
- if (DEBUG_BROADCAST) Slog.v(
- TAG, "Received BROADCAST_INTENT_MSG");
- <span style="background-color: rgb(255, 153, 0);">processNextBroadcast</span>(true);
- } break;
- case BROADCAST_TIMEOUT_MSG: {
- synchronized (mService) {
- broadcastTimeoutLocked(true);
- }
- } break;
- }
- }
- };
- </span>
收到BROADCAST_INTENT_MSG消息,调用processNextBroadcast()函数继续处理。processNextBroadcast()函数:
- <span style="font-size:14px;"> final void processNextBroadcast(boolean fromMsg){
- synchronized(mService) {
- // First, deliver any non-serialized broadcasts right away.
- while (mParallelBroadcasts.size() > 0) {
- //①无序广播,并且接收器为动态注册,直接调用deliverToRegisteredReceiverLocked()进行处理
- r = mParallelBroadcasts.remove(0);
- r.dispatchTime = SystemClock.uptimeMillis();
- r.dispatchClockTime = System.currentTimeMillis();
- final int N = r.receivers.size();
- if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast ["
- + mQueueName + "] " + r);
- for (int i=0; i<N; i++) {
- Object target = r.receivers.get(i);
- if (DEBUG_BROADCAST) Slog.v(TAG,
- "Delivering non-ordered on [" + mQueueName + "] to registered "
- + target + ": " + r);
- deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
- }
- addBroadcastToHistoryLocked(r);
- if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast ["
- + mQueueName + "] " + r);
- }
- // Now take care of the next serialized one...
- // If we are waiting for a process to come up to handle the next
- // broadcast, then do nothing at this point. Just in case, we
- // check that the process we're waiting for still exists.
- if (mPendingBroadcast != null) {
- if (DEBUG_BROADCAST_LIGHT) {
- Slog.v(TAG, "processNextBroadcast ["
- + mQueueName + "]: waiting for "
- + mPendingBroadcast.curApp);
- }
- boolean isDead;
- synchronized (mService.mPidsSelfLocked) {
- ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
- isDead = proc == null || proc.crashing;
- }
- if (!isDead) {
- // It's still alive, so keep waiting
- return;
- } else {
- Slog.w(TAG, "pending app ["
- + mQueueName + "]" + mPendingBroadcast.curApp
- + " died before responding to broadcast");
- mPendingBroadcast.state = BroadcastRecord.IDLE;
- mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
- mPendingBroadcast = null;
- }
- }
- boolean looped = false;
- do {
- if (mOrderedBroadcasts.size() == 0) {
- //②由broadcastIntentLocked()函数知道,mOrderedBroadcasts可保存两种类型广播,一种是无序广播,接收器为静态注册,另一种是有序广播,接收器是动态注册和静态注册的合并。如果mOrderedBroadcasts为空,直接返回。
- // No more broadcasts pending, so all done!
- mService.scheduleAppGcsLocked();
- if (looped) {
- // If we had finished the last ordered broadcast, then
- // make sure all processes have correct oom and sched
- // adjustments.
- mService.updateOomAdjLocked();
- }
- return;
- }
- //③按顺序取出mOrderedBroadcasts中的广播
- r = mOrderedBroadcasts.get(0);
- boolean forceReceive = false;
- // Ensure that even if something goes awry with the timeout
- // detection, we catch "hung" broadcasts here, discard them,
- // and continue to make progress.
- //
- // This is only done if the system is ready so that PRE_BOOT_COMPLETED
- // receivers don't get executed with timeouts. They're intended for
- // one time heavy lifting after system upgrades and can take
- // significant amounts of time.
- int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
- //④判断是否广播超时,超时则调用broadcastTimeoutLocked(false),forceReceive = true;
- if (mService.mProcessesReady && r.dispatchTime > 0) {
- long now = SystemClock.uptimeMillis();
- if ((numReceivers > 0) &&
- (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
- Slog.w(TAG, "Hung broadcast ["
- + mQueueName + "] discarded after timeout failure:"
- + " now=" + now
- + " dispatchTime=" + r.dispatchTime
- + " startTime=" + r.receiverTime
- + " intent=" + r.intent
- + " numReceivers=" + numReceivers
- + " nextReceiver=" + r.nextReceiver
- + " state=" + r.state);
- broadcastTimeoutLocked(false); // forcibly finish this broadcast
- forceReceive = true;
- r.state = BroadcastRecord.IDLE;
- }
- }
- if (r.state != BroadcastRecord.IDLE) {
- if (DEBUG_BROADCAST) Slog.d(TAG,
- "processNextBroadcast("
- + mQueueName + ") called when not idle (state="
- + r.state + ")");
- return;
- }
- if (r.receivers == null || r.nextReceiver >= numReceivers
- || r.resultAbort || forceReceive) {
- //⑤如果该广播没有接收器,或被终止继续传递,或超时,或(r.nextReceiver >= numReceivers)???则终结这个广播:如果指定了resultTo,那么调用performReceiveLocked()来将该广播发送到resultTo,然后从mOrderedBroadcasts中进行移除。
- // No more receivers for this broadcast! Send the final
- // result if requested...
- if (r.resultTo != null) {
- try {
- if (DEBUG_BROADCAST) {
- int seq = r.intent.getIntExtra("seq", -1);
- Slog.i(TAG, "Finishing broadcast ["
- + mQueueName + "] " + r.intent.getAction()
- + " seq=" + seq + " app=" + r.callerApp);
- }
- performReceiveLocked(r.callerApp, r.resultTo,
- new Intent(r.intent), r.resultCode,
- r.resultData, r.resultExtras, false, false, r.userId);
- // Set this to null so that the reference
- // (local and remote) isn't kept in the mBroadcastHistory.
- r.resultTo = null;
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure ["
- + mQueueName + "] sending broadcast result of "
- + r.intent, e);
- }
- }
- if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
- cancelBroadcastTimeoutLocked();
- if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
- + r);
- // ... and on to the next...
- addBroadcastToHistoryLocked(r);
- mOrderedBroadcasts.remove(0);
- r = null;
- looped = true;
- continue;
- }
- //⑥此while循环意在清除mOrderedBroadcasts中没有接收器、被终止继续传递、超时等广播。
- } while (r == null);
- // Get the next receiver...
- //
- int recIdx = r.nextReceiver++;
- // Keep track of when this receiver started, and make sure there
- // is a timeout message pending to kill it if need be.
- r.receiverTime = SystemClock.uptimeMillis();
- if (recIdx == 0) {
- r.dispatchTime = r.receiverTime;
- r.dispatchClockTime = System.currentTimeMillis();
- if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["
- + mQueueName + "] " + r);
- }
- if (! mPendingBroadcastTimeoutMessage) {
- long timeoutTime = r.receiverTime + mTimeoutPeriod;
- if (DEBUG_BROADCAST) Slog.v(TAG,
- "Submitting BROADCAST_TIMEOUT_MSG ["
- + mQueueName + "] for " + r + " at " + timeoutTime);
- setBroadcastTimeoutLocked(timeoutTime);
- }
- //⑦取出一个广播接收器,将该广播发送到该接收器(deliverToRegisteredReceiverLocked()),前面说了receivers保存着两种:静态接收器(无序广播)、静态和动态接收器的合并(有序广播)。如果是无序广播在deliverToRegisteredReceiverLocked()完这个接收器后,立马调用scheduleBroadcastsLocked()准备deliver给下一个接收器;如果是有序广播,则必须在deliver到当前接收器,并finished后(r.receiver == null)才能调用scheduleBroadcastsLocked()准备deliver给下一个接收器,如果没有finished,那么直接return。这块逻辑也是控制有序广播有序地的deliver给接收器的关键所在。
- Object nextReceiver = r.receivers.get(recIdx);
- if (nextReceiver instanceof BroadcastFilter) {
- // Simple case: this is a registered receiver who gets
- // a direct call.
- BroadcastFilter filter = (BroadcastFilter)nextReceiver;
- if (DEBUG_BROADCAST) Slog.v(TAG,
- "Delivering ordered ["
- + mQueueName + "] to registered "
- + filter + ": " + r);
- deliverToRegisteredReceiverLocked(r, filter, r.ordered);
- if (r.receiver == null || !r.ordered) {
- // The receiver has already finished, so schedule to
- // process the next one.
- if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing ["
- + mQueueName + "]: ordered="
- + r.ordered + " receiver=" + r.receiver);
- r.state = BroadcastRecord.IDLE;
- scheduleBroadcastsLocked();
- }
- return;
- }
- //⑧既然return掉了,后面的逻辑真不知道是干嘛的?
- …………
- }</span>
- <span style="font-size:14px;"> private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
- Intent intent, int resultCode, String data, Bundle extras,
- boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
- …………
- if (!skip) {
- // If this is not being sent as an ordered broadcast, then we
- // don't want to touch the fields that keep track of the current
- // state of ordered broadcasts.
- if (ordered) {
- r.receiver = filter.receiverList.receiver.asBinder();
- r.curFilter = filter;
- filter.receiverList.curBroadcast = r;
- r.state = BroadcastRecord.CALL_IN_RECEIVE;
- if (filter.receiverList.app != null) {
- // Bump hosting application to no longer be in background
- // scheduling class. Note that we can't do that if there
- // isn't an app... but we can only be in that case for
- // things that directly call the IActivityManager API, which
- // are already core system stuff so don't matter for this.
- r.curApp = filter.receiverList.app;
- filter.receiverList.app.curReceiver = r;
- mService.updateOomAdjLocked(r.curApp, true);
- }
- }
- try {
- if (DEBUG_BROADCAST_LIGHT) {
- int seq = r.intent.getIntExtra("seq", -1);
- Slog.i(TAG, "Delivering to " + filter
- + " (seq=" + seq + "): " + r);
- }
- performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
- new Intent(r.intent), r.resultCode, r.resultData,
- r.resultExtras, r.ordered, r.initialSticky, r.userId);
- if (ordered) {
- r.state = BroadcastRecord.CALL_DONE_RECEIVE;
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
- if (ordered) {
- r.receiver = null;
- r.curFilter = null;
- filter.receiverList.curBroadcast = null;
- if (filter.receiverList.app != null) {
- filter.receiverList.app.curReceiver = null;
- }
- }
- }
- }
- </span>
- <span style="font-size:14px;"> private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
- Intent intent, int resultCode, String data, Bundle extras,
- boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
- // Send the intent to the receiver asynchronously using one-way binder calls.
- if (app != null && app.thread != null) {
- // If we have an app thread, do the call through that so it is
- // correctly ordered with other one-way calls.
- app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
- data, extras, ordered, sticky, sendingUser, app.repProcState);
- } else {
- receiver.performReceive(intent, resultCode, data, extras, ordered,
- sticky, sendingUser);
- }
- }
- </span>
继续研究ReceiverDispatcher.performReceive():
- <span style="font-size:14px;"> public void performReceive(Intent intent, int resultCode, String data,
- Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
- if (ActivityThread.DEBUG_BROADCAST) {
- int seq = intent.getIntExtra("seq", -1);
- Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq
- + " to " + mReceiver);
- }
- Args args = new Args(intent, resultCode, data, extras, ordered,
- sticky, sendingUser);
- if (!mActivityThread.post(args)) {
- if (mRegistered && ordered) {
- IActivityManager mgr = ActivityManagerNative.getDefault();
- if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
- "Finishing sync broadcast to " + mReceiver);
- args.sendFinished(mgr);
- }
- }
- }
- </span>
- <span style="font-size:14px;"> public void run() {
- final BroadcastReceiver receiver = mReceiver;
- final boolean ordered = mOrdered;
- final IActivityManager mgr = ActivityManagerNative.getDefault();
- final Intent intent = mCurIntent;
- mCurIntent = null;
- if (receiver == null || mForgotten) {
- if (mRegistered && ordered) {
- if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
- "Finishing null broadcast to " + mReceiver);
- sendFinished(mgr);
- }
- return;
- }
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
- try {
- ClassLoader cl = mReceiver.getClass().getClassLoader();
- intent.setExtrasClassLoader(cl);
- setExtrasClassLoader(cl);
- receiver.setPendingResult(this);
- receiver.onReceive(mContext, intent);
- } catch (Exception e) {
- if (mRegistered && ordered) {
- if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
- "Finishing failed broadcast to " + mReceiver);
- sendFinished(mgr);
- }
- if (mInstrumentation == null ||
- !mInstrumentation.onException(mReceiver, e)) {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- throw new RuntimeException(
- "Error receiving broadcast " + intent
- + " in " + mReceiver, e);
- }
- }
- if (receiver.getPendingResult() != null) {
- finish();
- }
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- }
- }
- </span>
总结广播机制:①广播注册—上层应用调用registerReceiver()注册广播接收器时,AMS会成对保存IntentFilter和Intent.action,同时也会保存一个与广播接收器对应的Receiver;②广播发送—sendBroadcast()发送一个广播时,在AMS侧会对应生成一个BroadcastRecord,然后从①中保存的IntentFilter和Intent.action对中找出相同Intent.action的IntentFilter,最后将广播信息通过Binder机制的Receiver传递给上层应用的BroadcastReceiver对象,onReceive()函数自然将被调用。
文章中processNextBroadcast()函数理解有偏差,后续再修正。
待续。