广播的注册分为静态注册和动态注册,主要分析动态注册,可以从三个方面来分析;
- 广播的注册
- 广播的发送
- 广播的处理
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
//mBase -> ContextImpl
return mBase.registerReceiver(receiver, filter);
}
registerReceiver() 有多个重载函数,最终调用到以下函数。
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 赋值为 主线程的 Handler
scheduler = mMainThread.getHandler();
}
//代码一:获取 IIntentReceiver对象 mPackageInfo -> LoasedApk 类型
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
//代码二:调用 ActivityManagerProxy(AMP) 的 registerReceiver
return ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
} catch (RemoteException e) {
return null;
}
}
static final class ReceiverDispatcher {
//显然 IIntentReceiver 是一个 Binder 接口,跨进程通信
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;
}
ActivityManagerNative.getDefault() 最终会调用 ActivityManagerService#registerReceiver() 方法。
public Intent registerReceiver(...) {
...
ProcessRecord callerApp = null;
...
synchronized(this) {
if (caller != null) {
//获取调用者的进程信息
callerApp = getRecordForAppLocked(caller);
...
//获取 IntentFilter 中的 actions 信息
Iterator<String> actions = filter.actionsIterator();
if (actions == null) {
ArrayList<String> noAction = new ArrayList<String>(1);
noAction.add(null);
actions = noAction.iterator();
}
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
while (actions.hasNext()) {
String action = actions.next();
for (int id : userIds) {
//从mStickyBroadcasts中查看用户的sticky Intent
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
if (stickies != null) {
ArrayList<Intent> intents = stickies.get(action);
if (intents != null) {
if (stickyIntents == null) {
stickyIntents = new ArrayList<Intent>();
}
//把粘性广播添加到列表中
stickyIntents.addAll(intents);
}
}
}
}
}
...
synchronized (this) {
...
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
//对于未注册的广播,则创建接受者队列
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) {
final int totalReceiversForApp = rl.app.receivers.size();
if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
throw new IllegalStateException("Too many receivers, total of "
+ totalReceiversForApp + ", registered for pid: "
+ rl.pid + ", callerPackage: " + callerPackage);
}
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,并添加到接受者队列
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
if (rl.containsFilter(filter)) {
...
} else {
...
//新建的BroadcastFilter,添加到mReceiverResolver队列中
mReceiverResolver.addFilter(bf);
}
...
return sticky;
}
}
其实就是用来记录着所有已经注册的广播。
发送广播其实就是调用 sendBroadcast(),在 ContextImpl 里面。
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
...
// 调用 AMP.broadcastIntent
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
...
}
}
public final int broadcastIntent(...) {
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();
//调用 broadcastIntentLocked
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
}
private final int broadcastIntentLocked(...) {
...
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
//根据intent的flag来判断前台队列或者后台队列
BroadcastQueue queue = broadcastQueueForIntent(intent);
//创建BroadcastRecord
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
if (!replaced) {
//将BroadcastRecord加入到有序广播队列
queue.enqueueOrderedBroadcastLocked(r);
//处理广播
queue.scheduleBroadcastsLocked();
}
}
return ActivityManager.BROADCAST_SUCCESS;
}
把静态注册和动态注册的广播,按照优先级不同存储在不同的列表中,然后把列表合并到recevers 列表中。最后调用 BroadcastQueue的
scheduleBroadcastsLocked。
public void scheduleBroadcastsLocked() {
//Handler 发送消息 BroadcastHandler
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
private final class BroadcastHandler extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
//进行消息处理
processNextBroadcast(true);
} break;
...
}
}
final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
//处理无序广播
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
//分发广播给已注册的receiver
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
}
//将广播添加历史统计
addBroadcastToHistoryLocked(r);
}
...
}
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered) {
...
//检查广播的权限
...
//performReceiveLocked 处理广播
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;
}
...
}
}
BroadcastQueue#performReceiveLocked()
private static void performReceiveLocked(...) throws RemoteException {
//通过binder,向 receiver 发送intent
if (app != null) {
if (app.thread != null) {
//代码一:调用 ApplicationThreadProxy 类对应的方法
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} else {
...
}
} else {
//调用者进程为空,则执行该分支
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
public void scheduleRegisteredReceiver(...) throws RemoteException {
updateProcessState(processState, false);
//IIntentReceiver 的 performReceive 方法,具体实现 LoadedApk.ReceiverDispatcher.InnerReceive
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,sticky, sendingUser);
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
//把广播的 intent 对象封装为 Args
final Args args = new Args(intent, resultCode, data, extras, ordered,sticky, sendingUser);
...
// H 类 post
if (intent == null || !mActivityThread.post(args.getRunnable())) {
...
}
}
public final Runnable getRunnable() {
return () -> {
...
try {
...
//调用了onReceive 方法
receiver.onReceive(mContext, intent);
}
}