Android 应用与 Android 系统和其他 Android 应用之间可以相互收发广播消息,这与发布-订阅设计模式相似。这些广播会在所关注的事件发生时发送。举例来说,Android 系统会在发生各种系统事件时发送广播,例如系统启动或设备开始充电时。再比如,应用可以发送自定义广播来通知其他应用它们可能感兴趣的事件(本文源码基于Android 10 )
IntentFilter intentFilter = new IntentFilter(BROADCAST_TEST_MESSAGE); registerReceiver(receiver,intentFilter); 复制代码
frameworks/base/core/java/android/app/ContextImpl.java
@Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { return registerReceiver(receiver, filter, null, null); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { return registerReceiverInternal(receiver, getUserId(), filter, broadcastPermission, scheduler, getOuterContext(), 0);//1 } 复制代码
frameworks/base/core/java/android/app/ContextImpl.java
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context, int flags) { IIntentReceiver rd = null;//1 if (receiver != null) { if (mPackageInfo != null && context != null) { if (scheduler == null) { scheduler = mMainThread.getHandler();//2 } rd = mPackageInfo.getReceiverDispatcher( receiver, context, scheduler, mMainThread.getInstrumentation(), true);//3 } ..... } try { final Intent intent = ActivityManager.getService().registerReceiver( mMainThread.getApplicationThread(), mBasePackageName, rd, filter, broadcastPermission, userId, flags);//4 } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } 复制代码
frameworks/base/core/java/android/app/LoadedApk.java
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<>(); static final class ReceiverDispatcher { final static class InnerReceiver extends IIntentReceiver.Stub { ....... }//1 ReceiverDispatcher(BroadcastReceiver receiver, Context context, Handler activityThread, Instrumentation instrumentation, boolean registered) { ...... mIIntentReceiver = new InnerReceiver(this, !registered); mReceiver = receiver; mContext = context; mActivityThread = activityThread; mInstrumentation = instrumentation; mRegistered = registered; mLocation = new IntentReceiverLeaked(null); mLocation.fillInStackTrace(); }//2 ....... 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);//3 if (registered) { if (map == null) { map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); mReceivers.put(context, map); } map.put(r, rd);//4 } } else { rd.validate(context, handler); } rd.mForgotten = false; return rd.getIIntentReceiver();//5 } } ..... IIntentReceiver getIIntentReceiver() { return mIIntentReceiver; }//6 } 复制代码
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId, int flags) { ...... synchronized (this) { 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; } mRegisteredReceivers.put(receiver.asBinder(), rl);//1 } ....... BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission, callingUid, userId, instantApp, visibleToInstantApps);//2 if (rl.containsFilter(filter)) { Slog.w(TAG, "Receiver with filter " + filter + " already registered for pid " + rl.pid + ", callerPackage is " + callerPackage); } else { rl.add(bf);//3 ..... mReceiverResolver.addFilter(bf);//4 } ..... } 复制代码
sendBroadcast(new Intent(BROADCAST_TEST_MESSAGE)); 复制代码
frameworks/base/core/java/android/app/ContextImpl.java
@Override public void sendBroadcast(Intent intent) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } 复制代码
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, 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(); try { return broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions, serialized, sticky, callingPid, callingUid, callingUid, callingPid, userId);//2 } finally { Binder.restoreCallingIdentity(origId); } } } 复制代码
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId, boolean allowBackgroundActivityStarts) { intent = new Intent(intent); ..... // Add to the sticky list if requested. if (sticky) { if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, callingPid, callingUid)//1 != PackageManager.PERMISSION_GRANTED) { ...... } ...... // We use userId directly here, since the "all" target is maintained // as a separate set of sticky broadcasts. if (userId != UserHandle.USER_ALL) { // But first, if this is not a broadcast to all users, then // make sure it doesn't conflict with an existing broadcast to // all users. ........ } } ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); if (stickies == null) { stickies = new ArrayMap<>(); mStickyBroadcasts.put(userId, stickies);//2 } ...... 复制代码
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
// 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, callingUid, users);//1 } if (intent.getComponent() == null) { if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) { // Query one target user at a time, excluding shell-restricted users ....... } else { registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);//2 } } final boolean replacePending = (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;//3 ...... int NR = registeredReceivers != null ? registeredReceivers.size() : 0; if (!ordered && NR > 0) { // If we are not serializing this broadcast, then send the // registered receivers separately so they don't wait for the // components to be launched. if (isCallerSystem) { checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, registeredReceivers); } final BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId, allowBackgroundActivityStarts, timeoutExempt);//4 final boolean replaced = replacePending && (queue.replaceParallelBroadcastLocked(r) != null);//5 // Note: We assume resultTo is null for non-ordered broadcasts. if (!replaced) {//6 queue.enqueueParallelBroadcastLocked(r);//7 queue.scheduleBroadcastsLocked();//8 } registeredReceivers = null;//9 NR = 0; } 复制代码
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
public void scheduleBroadcastsLocked() { ....... if (mBroadcastsScheduled) { return; } mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));//1 mBroadcastsScheduled = true; } 复制代码
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
final BroadcastHandler mHandler; 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: { ..... processNextBroadcast(true);//1 } break; ....... } } } 复制代码
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
final void processNextBroadcast(boolean fromMsg) { synchronized (mService) { processNextBroadcastLocked(fromMsg, false); } } final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) { BroadcastRecord r; ....... if (fromMsg) { mBroadcastsScheduled = false;//1 } // First, deliver any non-serialized broadcasts right away. while (mParallelBroadcasts.size() > 0) { r = mParallelBroadcasts.remove(0);//2 ...... final int N = r.receivers.size(); ...... for (int i=0; i<N; i++) { Object target = r.receivers.get(i);//3 ....... deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);//4 } addBroadcastToHistoryLocked(r); ......... } ..... } 复制代码
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index) { ....... try { ....... performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, r.ordered, r.initialSticky, r.userId); ....... } } catch (RemoteException e) { ....... } 复制代码
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
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. try { app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser, app.getReportedProcState());//1 } catch (RemoteException ex) { ...... } .... } else { receiver.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);//2 } } 复制代码
frameworks/base/core/java/android/app/ActivityThread.java
// 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);//1 } 复制代码
frameworks/base/core/java/android/app/LoadedApk.java
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; } @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { final LoadedApk.ReceiverDispatcher rd; ..... rd = mDispatcher.get(); ....... if (rd != null) { rd.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);//1 } ....... } } } 复制代码
frameworks/base/core/java/android/app/LoadedApk.java
static final class ReceiverDispatcher { ...... final Handler mActivityThread; ...... public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { final Args args = new Args(intent, resultCode, data, extras, ordered, sticky, sendingUser);//1 if (intent == null || !mActivityThread.post(args.getRunnable())//2 { ....... } } 复制代码
frameworks/base/core/java/android/app/LoadedApk.java
final class Args extends BroadcastReceiver.PendingResult { private Intent mCurIntent; private final boolean mOrdered; private boolean mDispatched; private boolean mRunCalled; ........ public final Runnable getRunnable() { return () -> { final BroadcastReceiver receiver = mReceiver; ....... final IActivityManager mgr = ActivityManager.getService(); final Intent intent = mCurIntent; mCurIntent = null; mDispatched = true; mRunCalled = true; ....... try { ..... receiver.onReceive(mContext, intent);//1 } catch (Exception e) { ....... } ..... }; } } 复制代码