广播的注册分为静态注册和动态注册,其中静态注册的广播在应用安装时由系统自动完成注册,具体来说由PMS 来完成整个注册过程,除了广播外,其他三大组件也是在应用安装时由PMS 解析并注册的。这里只分析广播的动态注册过程,动态注册的过程是从 ContextWrapper 的registerReceiver 方法开始的,如下所示:
@Override public Intent registerReceiver( BroadcastReceiver receiver, IntentFilter filter) { return mBase.registerReceiver(receiver, filter); }
和Service 类似,ContextWrapper 并未完成实际的注册工作,而是交给了ContextImpl 来完成,ContextImpl 的 registerReceiverInternal 方法如下所示:
final LoadedApk mPackageInfo; private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context) { IIntentReceiver rd = null; if (receiver != null) { if (mPackageInfo != null && context != null) { if (scheduler == null) { scheduler = mMainThread.getHandler(); } //从 mPackageInfo 获取IIntentReceiver 对象 rd = mPackageInfo.getReceiverDispatcher( receiver, context, scheduler, mMainThread.getInstrumentation(), true); } else { if (scheduler == null) { scheduler = mMainThread.getHandler(); } //创建 IIntentReceiver 对象 rd = new LoadedApk.ReceiverDispatcher( receiver, context, scheduler, null, true).getIIntentReceiver(); } } try { //发送广播注册请求 return ActivityManagerNative.getDefault().registerReceiver( mMainThread.getApplicationThread(), mBasePackageName, rd, filter, broadcastPermission, userId); } catch (RemoteException e) { return null; } }
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r, Context context, Handler handler, Instrumentation instrumentation, boolean registered) { synchronized (mReceivers) { LoadedApk.ReceiverDispatcher rd = null; ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; if (registered) { map = mReceivers.get(context); if (map != null) { rd = map.get(r); } } if (rd == null) { rd = new ReceiverDispatcher(r, context, handler, instrumentation, registered); if (registered) { if (map == null) { map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); mReceivers.put(context, map); } map.put(r, rd); } } else { rd.validate(context, handler); } rd.mForgotten = false; return rd.getIIntentReceiver(); } }
public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { enforceNotIsolatedCaller("registerReceiver"); ... synchronized (this) { if (callerApp != null && (callerApp.thread == null || callerApp.thread.asBinder() != caller.asBinder())) { // Original caller already died return null; } ReceiverList rl = 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; } //存储InnerReceiver mRegisteredReceivers.put(receiver.asBinder(), rl); } else if (rl.uid != callingUid) { throw new IllegalArgumentException( "Receiver requested to register for uid " + callingUid + " was previously registered for uid " + rl.uid); } else if (rl.pid != callingPid) { throw new IllegalArgumentException( "Receiver requested to register for pid " + callingPid + " was previously registered for pid " + rl.pid); } else if (rl.userId != userId) { throw new IllegalArgumentException( "Receiver requested to register for user " + userId + " was previously registered for user " + rl.userId); } BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission, callingUid, userId); rl.add(bf); if (!bf.debugCheck()) { Slog.w(TAG, "==> For Dynamic broadcast"); } //存储IntentFilter mReceiverResolver.addFilter(bf); ... }
@Override public void sendBroadcast(Intent intent) { mBase.sendBroadcast(intent); }
和Service 类似,具体的发送工作交由 ContextImpl的 sendBroadcast 完成,如下所示:
@Override public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); String[] receiverPermissions = receiverPermission == null ? null : new String[] {receiverPermission}; try { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false, getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } }
在sendBroadcast 中调用了AMS 的 broadcastIntent 方法,AMS 的broadcastIntent 源码如下所示:
public final int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options, boolean serialized, boolean sticky, int userId) { enforceNotIsolatedCaller("broadcastIntent"); synchronized(this) { intent = verifyBroadcastLocked(intent); final ProcessRecord callerApp = getRecordForAppLocked(caller); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); int res = broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, null, serialized, sticky, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; } }
在broadcastIntentLocked 有如下一段代码:
// By default broadcasts do not go to stopped apps. intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
这表示在Android5.0 中,默认情况下广播不会发送给已经停止的应用。处于停止的应用无法接收到开机广播。在broadcastIntentLocked 内部,会根据 intent-filter 查找出匹配的广播接受者并经过一系列的条件过滤,最终会将满足条件的广播接收者添加到 BroadcastQueue 中,接着BroadcastQueue 就会将广播发送给相应的广播接受者,过程的源码如下所示:
if ((receivers != null && receivers.size() > 0) || resultTo != null) { BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r + ": prev had " + queue.mOrderedBroadcasts.size()); if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST, "Enqueueing broadcast " + r.intent.getAction()); boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); if (!replaced) { queue.enqueueOrderedBroadcastLocked(r); queue.scheduleBroadcastsLocked(); } }
在BroadcastQueue 的广播发送实现如下所示:
public void scheduleBroadcastsLocked() { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts [" + mQueueName + "]: current=" + mBroadcastsScheduled); if (mBroadcastsScheduled) { return; } mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this)); mBroadcastsScheduled = true; }
BroadcastQueue 的 scheduleBroadcastsLocked 并没有立即发送广播,而是发送了一条 BROADCAST_INTENT_MSG 类型的消息,BroadcastQueue 接收到消息后会调用 processNextBroadcast 方法,如下所示:
private final class BroadcastHandler extends Handler { public BroadcastHandler(Looper looper) { super(looper, null, true); } @Override public void handleMessage(Message msg) { switch (msg.what) { case BROADCAST_INTENT_MSG: { if (DEBUG_BROADCAST) Slog.v( TAG_BROADCAST, "Received BROADCAST_INTENT_MSG"); processNextBroadcast(true); } break; case BROADCAST_TIMEOUT_MSG: { synchronized (mService) { broadcastTimeoutLocked(true); } } break; case SCHEDULE_TEMP_WHITELIST_MSG: { DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController; if (dic != null) { dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1), msg.arg2, true, (String)msg.obj); } } break; } } };
BroadcastQueue 的 processNextBroadcast 方法源码如下:
final void processNextBroadcast(boolean fromMsg) { ... // First, deliver any non-serialized broadcasts right away. while (mParallelBroadcasts.size() > 0) { 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_BROADCAST, "Processing parallel broadcast [" + mQueueName + "] " + r); for (int i=0; i<N; i++) { Object target = r.receivers.get(i); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Delivering non-ordered on [" + mQueueName + "] to registered " + target + ": " + r); //发送广播给特定接受者 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false); } addBroadcastToHistoryLocked(r); if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast [" + mQueueName + "] " + r); } ... }
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered) { ... try { if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST, "Delivering to " + filter + " : " + 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; } } } }
performReceiveLocked 的具体实现如下所示:
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) { if (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 { // Application has died. Receiver doesn't exist. throw new RemoteException("app.thread must not be null"); } } else { receiver.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser); } }
由于广播接收者会调起应用程序,故app.thread 不为 null,所以这里最终会调用 AMS 的scheduleRegisteredReceiver 方法,如下所示:
// This function exists to make sure all receiver dispatching is // correctly ordered, since these are one-way calls and the binder driver // applies transaction ordering per object for such calls. public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky, int sendingUser, int processState) throws RemoteException { updateProcessState(processState, false); receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky, sendingUser); }
在scheduleRegisteredReceiver 中会调用 IIntentReceiver 的performReceive 方法,即调用的是LoadedApk.ReceiverDispatcher 的 performReceive 方法,如下所示:
static final class ReceiverDispatcher { final static class InnerReceiver extends IIntentReceiver.Stub { final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher; final LoadedApk.ReceiverDispatcher mStrongRef; InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) { mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd); mStrongRef = strong ? rd : null; } public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { LoadedApk.ReceiverDispatcher rd = mDispatcher.get(); if (ActivityThread.DEBUG_BROADCAST) { int seq = intent.getIntExtra("seq", -1); Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction() + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null)); } if (rd != null) { rd.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser); } else { // The activity manager dispatched a broadcast to a registered // receiver in this process, but before it could be delivered the // receiver was unregistered. Acknowledge the broadcast on its // behalf so that the system's broadcast sequence can continue. if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, "Finishing broadcast to unregistered receiver"); IActivityManager mgr = ActivityManagerNative.getDefault(); try { if (extras != null) { extras.setAllowFds(false); } mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags()); } catch (RemoteException e) { Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver"); } } } } ... 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)) {//通过 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); } } } }
在performReceive 中,会创建一个Args 对象,并通过 mActivityThread 的post 方法来执行Args 中的逻辑,而Args 实现了 Runnable 接口。mActivityThread 就是ActivityThread 中的 H,Args 的源码如下:
final class Args extends BroadcastReceiver.PendingResult implements Runnable { private Intent mCurIntent; private final boolean mOrdered; public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras, boolean ordered, boolean sticky, int sendingUser) { super(resultCode, resultData, resultExtras, mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered, sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags()); mCurIntent = intent; mOrdered = ordered; } public void run() { final BroadcastReceiver receiver = mReceiver; final boolean ordered = mOrdered; ... 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); } } ... } }
BroadcastReceiver 发送/接收过程