1、相关代码
\frameworks\base\core\java\android\app\ContextImpl.java
\frameworks\base\core\java\android\app\LoadedApk.java
\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
\frameworks\base\services\core\java\com\android\server\am\BroadcastQueue.java
\frameworks\base\core\java\android\app\BroadcastOptions.java
\frameworks\base\services\core\java\com\android\server\am\ReceiverList.java
\frameworks\base\services\core\java\com\android\server\IntentResolver.java
\frameworks\base\services\core\java\com\android\server\am\BroadcastFilter.java
2.1广播动态注册流程
简要流程如上图,注册过程主要通过AMS调用,将注册的intentFilter添加到BroadcastFilter中的队列mFilters中,同时将IIntentReceiver对象添加到mRegisteredReceivers中。
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {
ArrayList<Intent> stickyIntents = null;
//...... 对调用者,instantApp、flag等做检查
//......处理粘性广播,将粘性广播加到粘性广播队列中
synchronized (this) {
//从现有队列中查找本地的IIntentReceiver
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
//如果当前没有,则新建,并且每个应用只能创建1000个receiver超过会报异常
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
//......
mRegisteredReceivers.put(receiver.asBinder(), rl);
} else if (rl.uid != callingUid) {
//跟已有uid不同报异常
} else if (rl.pid != callingPid) {
//跟已有pid不同报异常
} else if (rl.userId != userId) {
//跟已有userId不同报异常
}
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
if (rl.containsFilter(filter)) {
//intentfilter已存在,不再重复添加
} else {
rl.add(bf);
//添加intentFilter到mReceiverResolver表中
mReceiverResolver.addFilter(bf);
}
if (allSticky != null) {
//发送粘性广播
for (int i = 0; i < stickyCount; i++) {
Intent intent = allSticky.get(i);
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, -1, -1, false, null, null, OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
//......
}
}
注册过程主要涉及两个重要标量:
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
= new IntentResolver<BroadcastFilter, BroadcastFilter>() {
//......
};
final class ReceiverList extends ArrayList<BroadcastFilter>
implements IBinder.DeathRecipient {
final ActivityManagerService owner;
public final IIntentReceiver receiver;
public final ProcessRecord app;
public final int pid;
public final int uid;
public final int userId;
BroadcastRecord curBroadcast = null;
boolean linkedToDeath = false;
final class BroadcastFilter extends IntentFilter {
// Back-pointer to the list this filter is in.
final ReceiverList receiverList;
final String packageName;
final String requiredPermission;
final int owningUid;
final int owningUserId;
final boolean instantApp;
final boolean visibleToInstantApp;
ReceiverList类相当于我们代码中的具体receiver,BroadcastFilter则相当于我们在注册广播时候施使用的intentFilter,一个进程不能注册超过1000个receiver,每个receiver中可以有多个BroadcastFilte,每次注册时候,先查找该receiver是否已经存在于当前的mRegisteredReceivers列表中了,如果已经存在,则检查这次注册者的pid、uid、userId是否跟已经存在的receiver中的这三个值相同,不同则抛出异常。
然后根据现有的或者新生成的ReceiverList名称rl,生成BroadcastFilter,如果该rl中已经包含给intentFilter,表示该已经存在了相同的receiver,包含了相同的intentfilter,不用再重复注册了,如果不包含,则将新生成的BroadcastFilter加入到rl中,将新建的BroadcastFilter加入到mReceiverResolver中。
解除注册,最重要的就是从这两个表中移出对象:
void removeReceiverLocked(ReceiverList rl) {
mRegisteredReceivers.remove(rl.receiver.asBinder());
for (int i = rl.size() - 1; i >= 0; i--) {
mReceiverResolver.removeFilter(rl.get(i));
}
}
2.2 广播发送流程
广播发送简略流程如上图所示,在进行了一些列的检查,包括参数,调用者,广播flag,特殊action,系统广播,等之后,从mReceiverResolver中检索出广播接收者,然后按照优先无序广播,之后发送有序广播的顺序,依次调用所有接收者的IIntentReceiver中的onReceive中。
两个广播发送序列,前台序列、后台序列
BroadcastQueue mFgBroadcastQueue;
BroadcastQueue mBgBroadcastQueue;
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();
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;
}
}
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,
boole