之前整理了广播的动态注册过程《广播的注册过程》,本文接着梳理广播的发送和接收过程,广播的发送同样是调用到ContextWrapper类的sendBroadcast方法:
Context mBase;
@Override
public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}
由上面的代码可知,ContextWrapper也没有做任何真正发送广播的操作,而是将具体工作转嫁给了ContextImpl类型的mBase,调用了mBase的sendBroadcast方法:
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
//注释1 跨进程调用
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();
}
}
在注释1处ActivityManager.getService()获取到的是AMS的一个Binder代理,所以最终调用到了AMS的broadcastIntent方法,在broadcastIntent里又调用了broadcastIntentLocked方法:
@GuardedBy("this")
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 userId) {
...........................
//注释2
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, 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());
final BroadcastRecord oldRecord =
replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
// Replaced, fire the result-to receiver.
if (oldRecord.resultTo != null) {
final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
try {
oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
oldRecord.intent,
Activity.RESULT_CANCELED, null, null,
false, false, oldRecord.userId);
} catch (RemoteException e) {
Slog.w(TAG, "Failure ["
+ queue.mQueueName + "] sending broadcast result of "
+ intent, e);
}
}
} else {
queue.enqueueOrderedBroadcastLocked(r);
//注释3
queue.scheduleBroadcastsLocked();
}
} else {
// There was nobody interested in the broadcast, but we still want to record
// that it happened.
if (intent.getComponent() == null && intent.getPackage() == null
&& (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
// This was an implicit broadcast... let's record it for posterity.
addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
}
}
return ActivityManager.BROADCAST_SUCCESS;
}
注释2处的receivers列表里存储了所有合法的广播接收者信息(包括有序和无序),在注释3处调用了BroadcastQueue的scheduleBroadcastsLocked方法:
public void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
+ mQueueName + "]: current="
+ mBroadcastsScheduled);
if (mBroadcastsScheduled) {
return;
}
//注释4
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
在注释4处发送了一个handler消息,由于mHandler的类型是BroadcastHandler,那消息的处理肯定在BroadcastHandler的handleMessage方法里,BroadcastHandler是BroadcastQueue的一个内部类,下面看下BroadcastHandler的相关源码:
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");
//注释5
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
}
从注释5处可知,这是处理注释4处发送的handler消息BROADCAST_INTENT_MSG的地方,此处调用到了BroadcastQueue的processNextBroadcast方法:
final void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
//注释6
processNextBroadcastLocked(fromMsg, false);
}
}
在注释6处又调用到了processNextBroadcastLocked方法:
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
BroadcastRecord r;
.................
if (fromMsg) {
mBroadcastsScheduled = false;
}
// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) {//注释7
r = mParallelBroadcasts.remove(0);//注释8
.................
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
.................
//注释9
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
.................
}
.................
}
mParallelBroadcasts是存储无序广播信息的列表,在注释7和8处遍历无序广播列表,并从列表中逐个取出BroadcastRecord类型的r对象(记录着广播信息),在注释9处把广播信息发送给对应的广播接收者。deliverToRegisteredReceiverLocked方法的源码如下:
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
.................
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
.................
}
上述代码中又继续调用了performReceiveLocked方法:
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
.................
//注释10
if (app != null) {
if (app.thread != null) {
try {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser,
}
.................
}
}
.................
}
在注释10处的app.thread是ApplicationThread,看下scheduleRegisteredReceiver方法:
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);
//注释11
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
在注释11处的地方又继续调用了LoadedApk.ReceiverDispatcher.InnerReceiver类型的receiver的performReceive方法,下面继续跟下源码:
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
.................
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;
.................
//注释12
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
}
.................
}
在注释12处调用了rd的performReceive方法,rd是LoadedApk.ReceiverDispatcher类型的,下面继续看下performReceive方法源码:
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
//注释13
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
.................
//注释14
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}
在注释13处,将广播的intent等相关信息都封装到了Args对象里面,在注释14处通过Handler类型的mActivityThread(就是ActivityThread中的H)的post方法,将args.getRunnable()对象post到主线程的消息队列中,最终会执行到Args里的Runnable的run方法里:
static final class ReceiverDispatcher {
.................
final BroadcastReceiver mReceiver;
.................
final class Args extends BroadcastReceiver.PendingResult {
.................
public final Runnable getRunnable() {
return () -> {
.................
//注释15
final BroadcastReceiver receiver = mReceiver;
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//注释16
receiver.onReceive(mContext, intent);
}
.................
}
}
}
}
在注释15处的receiver赋值为之前保存的App本地进程的BroadcastReceiver对象,在注释16处调用了receiver.onReceive方法,这样在App里注册的对应广播接收者就接收到广播消息了。