1、动态注册广播接收者
//ContextImpl.java
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext(), 0);
}
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
//IIntentReceiver类型的rd用来跨进程通信
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
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 {
//跨进程调用AMS的registerReceiver
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
首先获取到IIntentReceiver类型的rd对象,该对象是用来进行跨进程通信的。接着跨进行调用到ActivityManagerService的registerReceiver方法,传入了rd和filter作为参数。BroadcastReceiver实际上是不支持跨进程传输的,我们真正向AMS注册的是rd和filter。而当有广播发送到AMS时候,AMS就是通过广播找到匹配的IIntentReceiver,而IIntentReceiver的本质就是Binder,然后就可以跨进程调用到客户端的IIntentReceiver方法,而IIntentReceiver持有ReceiverDispatcher,ReceiverDispatcher持有BroadcastReceiver,这样就可以调用到BroadcastReceiver的onReceive方法。
接着分析ActivityManagerService的registerReceiver方法
//ActivityManagerService.java
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
synchronized(this) {
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
}
Iterator<String> actions = filter.actionsIterator();
//根据action和userId获取到所有的粘性广播
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
while (actions.hasNext()) {
String action = actions.next();
for (int id : userIds) {
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);
}
}
}
}
}
//收集所有的和filter匹配的粘性广播
ArrayList<Intent> allSticky = null;
if (stickyIntents != null) {
final ContentResolver resolver = mContext.getContentResolver();
// Look for any matching sticky broadcasts...
for (int i = 0, N = stickyIntents.size(); i < N; i++) {
Intent intent = stickyIntents.get(i);
if (filter.match(resolver, intent, true, TAG) >= 0) {
if (allSticky == null) {
allSticky = new ArrayList<Intent>();
}
allSticky.add(intent);
}
}
}
synchronized (this) {
if (callerApp != null && (callerApp.thread == null
|| callerApp.thread.asBinder() != caller.asBinder())) {
// Original caller already died
return null;
}
//把客户端传过来的IIntentReceiver类型的receiver保存到ReceiverList中
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
mRegisteredReceivers.put(receiver.asBinder(), rl);
}
//把ReceiverList和filter封装到BroadcastFilter中
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
rl.add(bf);
//接着将BroadcastFilter添加到mReceiverResolver中
//当AMS接收到广播就可以通过mReceiverResolver找到对应的广播接收者
mReceiverResolver.addFilter(bf);
//如果AMS中存在粘性广播就可以发送给我们的广播接收者了
if (allSticky != null) {
ArrayList receivers = new ArrayList();
receivers.add(bf);
final int stickyCount = allSticky.size();
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, AppOpsManager.OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
return sticky;
}
}
这样AMS的广播接收者动态注册流程就分析完了,接着是广播的发送过程。主要分析普通广播的工作流程。
2、普通广播的发送
//ContextImpl.java
public void sendBroadcast(Intent intent) {
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();
}
}
跨进程调用到AMS的broadcastIntent方法。
//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) {
synchronized(this) {
//验证广播是否合法
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
//调用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;
}
}
//ActivityManagerService.java
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent...boolean ordered...) {
intent = new Intent(intent);
//保存所有静态注册的广播
List receivers = null;
//保存所有动态注册的广播
List<BroadcastFilter> registeredReceivers = null;
// 如果我们指定了FLAG_RECEIVER_REGISTERED_ONLY这个标志,那么就不会取收集静态注册的广播接收
//者了,此时广播只会发送给动态注册的接收者
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
//获取所有静态注册的和intent匹配的广播接收者
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) {
...
//获取所有动态注册的和intent匹配的广播接收者
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, userId);
}
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
//如果是无序广播,优先将其发送给动态注册的广播接收者
if (!ordered && NR > 0) {
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(intent...registeredReceivers...);
final boolean replaced = replacePending
&& (queue.replaceParallelBroadcastLocked(r) != null);
if (!replaced) {
//将无序广播插入mParallelBroadcasts队列
queue.enqueueParallelBroadcastLocked(r);
//将广播发送给对应的广播接收者
queue.scheduleBroadcastsLocked();
}
//对于无序广播来说,已经将其发送给动态注册的广播接收器了,可以将registeredReceivers置空
registeredReceivers = null;
NR = 0;
}
int ir = 0;
if (receivers != null) {
// 如果是有序广播,需要将receivers和registeredReceivers合并在一起
while (it < NT && ir < NR) {
if (curt == null) {
curt = (ResolveInfo)receivers.get(it);
}
if (curr == null) {
curr = registeredReceivers.get(ir);
}
if (curr.getPriority() >= curt.priority) {
// Insert this broadcast record into the final list.
receivers.add(it, curr);
ir++;
curr = null;
it++;
NT++;
} else {
// Skip to the next ResolveInfo in the final list.
it++;
curt = null;
}
}
}
while (ir < NR) {
if (receivers == null) {
receivers = new ArrayList();
}
receivers.add(registeredReceivers.get(ir));
ir++;
}
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent...);
final BroadcastRecord oldRecord =
replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
} else {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
return ActivityManager.BROADCAST_SUCCESS;
}
接着分析queue.scheduleBroadcastsLocked()是如何发送广播的
//BroadcastQueue.java
//执行广播的发送
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
//发送了一条消息
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
//BroadcastQueue.java
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);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
}
//BroadcastQueue.java
final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
BroadcastRecord r;
if (fromMsg) {
mBroadcastsScheduled = false;
}
//只分析无序广播,其他的就不看了
// 遍历所有的无序广播
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
//将无序广播直接发送给对应的广播接收者
//前面分析过BroadcastFilter封装了广播接收者相关的信息
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
}
}
}
//BroadcastQueue.java
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
try {
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup){
} else {
//走到这里
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,new Intent(r.intent),...);
}
} catch (RemoteException e) {
}
}
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
if (app != null) {
//广播接收者所在的进程存在并且正在运行
if (app.thread != null) {
try {
//跨进程调用
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} catch (RemoteException ex) {}
} else {}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
这里的app.thread指代ApplicationThread,所以会跨进程调用到的广播接收者所在的进程的ApplicationThread的scheduleRegisteredReceiver方法。
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky...) throws RemoteException {
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
这里调用了IIntentReceiver类型的receiver的performReceive方法,InnerReceiver继承自IIntentReceiver.Stub,是Binder通信的服务端,而IIntentReceiver则是Binder通信的客户端,本质就是AIDL。
//LoadedApk.java
LoadedApk.ReceiverDispatcher.InnerReceiver
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
rd = null;
} else {
rd = mDispatcher.get();
}
if (rd != null) {
//调用到ReceiverDispatcher的performReceive方法
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
}
}
}
//ReceiverDispatcher#performReceive
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);
//调用到args.getRunnable()
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);
}
}
}
static final class ReceiverDispatcher {
final IIntentReceiver.Stub mIIntentReceiver;
final BroadcastReceiver mReceiver;
final Context mContext;
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
mIIntentReceiver = new InnerReceiver(this, !registered);
mReceiver = receiver;
mContext = context;
}
final class Args extends BroadcastReceiver.PendingResult {
private Intent mCurIntent;
private final boolean mOrdered;
public Args(...){
mCurIntent = intent;
mOrdered = ordered;
}
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final Intent intent = mCurIntent;
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//这里调用了广播接收者的onReceive方法
receiver.onReceive(mContext, intent);
}
};
}
}
}
到这里无序广播的发送和接受就分析完成了。
3、静态注册广播接收者
广播接收者的静态注册由PackageManagerService在启动或者程序安装的时候帮我们完成,只需要我们在AndroidManifest.xml清单文件中注册即可。关于PackageManagerService的我们知识不再本篇的范围。
PackageManagerService的scanPackageLI方法会调用到PackageParser的parsePackage方法,最终会调用到PackageParser的parseBaseApplication
private boolean parseBaseApplication(Package owner, Resources res,
XmlResourceParser parser, int flags, String[] outError)
throws XmlPullParserException, IOException {
//下面的代码就完成了AndroidManifest.xml中四大组件的解析过程
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("activity")) {
Activity a = parseActivity(owner, res, parser, flags, outError, false,
owner.baseHardwareAccelerated);
if (a == null) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return false;
}
owner.activities.add(a);
} else if (tagName.equals("receiver")) {
//解析广播接收者,这个Activity只是一种数据类型,用来封装receiver的信息。
//需要注意它和上面的"activity"共有了一个数据类型,给人的感觉有点奇怪
Activity a = parseActivity(owner, res, parser, flags, outError, true, false);
if (a == null) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return false;
}
//将广播接收者信息添加到Package的receivers列表里
owner.receivers.add(a);
} else if (tagName.equals("service")) {
Service s = parseService(owner, res, parser, flags, outError);
if (s == null) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return false;
}
owner.services.add(s);
} else if (tagName.equals("provider")) {
Provider p = parseProvider(owner, res, parser, flags, outError);
if (p == null) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return false;
}
owner.providers.add(p);
}
}
return true;
}
public final static class Package implements Parcelable {
public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
//保存了清单文件中的所有广播接收者
public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
public final ArrayList<Service> services = new ArrayList<Service>(0);
}
到这里广播接收者的静态注册就分析完了。那么广播又是如何发送到静态注册的广播接收者呢?
前面已经分析过当发送广播时,会调用到ActivityManagerService的broadcastIntentLocked方法,其中有段这样的代码:
//ActivityManagerService.java
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent...) {
intent = new Intent(intent);
//...
List receivers = null;
// Need to resolve the intent to interested receivers...
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
//会去PackageManagerService查询,获取匹配的静态注册的广播信息
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent...);
final BroadcastRecord oldRecord =
replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
} else {
//然后广播会被添加到mOrderedBroadcasts列表
queue.enqueueOrderedBroadcastLocked(r);
//执行广播的发送
queue.scheduleBroadcastsLocked();
}
}
}
接着分析BroadcastQueue的scheduleBroadcastsLocked。
//BroadcastQueue.java
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
private final class BroadcastHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
processNextBroadcast(true);
} break;
}
}
}
最后又进入了BroadcastQueue的processNextBroadcast方法,这里我们只看mOrderedBroadcasts列表相关的逻辑。
//BroadcastQueue.java
final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
BroadcastRecord r;
do {
if (mOrderedBroadcasts.size() == 0) {
return;
}
//拿到队列的第一个元素
r = mOrderedBroadcasts.get(0);
...
} while (r == null);
//获取广播接收者的一些包名信息,因为静态注册的接收者我们没有实例化,因为系统会帮助我们实例化
ResolveInfo info =
(ResolveInfo)nextReceiver;
ComponentName component = new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
//...
// 广播接收者所在的进程已经运行
if (app != null && app.thread != null && !app.killed) {
try {
app.addPackage(info.activityInfo.packageName,
info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
//会调用到这里,完成广播的发送
processCurBroadcastLocked(r, app);
return;
}
}
// 如果广播接收者所在进程没启动,需要先启动它
if ((r.curApp=mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo,...) {
...
return;
}
}
}
接着分析BroadcastQueue的processCurBroadcastLocked方法
//BroadcastQueue.java
private final void processCurBroadcastLocked(BroadcastRecord r,
ProcessRecord app) throws RemoteException {
...
try {
//最终调用到ApplicationThread的scheduleReceiver方法
app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver...);
}
}
//ActivityThread.java
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
private class H extends Handler {
public void handleMessage(Message msg) {
case RECEIVER:
handleReceiver((ReceiverData)msg.obj);
break;
}
}
发送了一个H.RECEIVER消息,然后调用了handleReceiver方法,
private void handleReceiver(ReceiverData data) {
String component = data.intent.getComponent().getClassName();
BroadcastReceiver receiver;
try {
app = packageInfo.makeApplication(false, mInstrumentation);
context = (ContextImpl) app.getBaseContext();
if (data.info.splitName != null) {
context = (ContextImpl) context.createContextForSplit(data.info.splitName);
}
java.lang.ClassLoader cl = context.getClassLoader();
data.intent.setExtrasClassLoader(cl);
data.intent.prepareToEnterProcess();
data.setExtrasClassLoader(cl);
//通过反射创建了BroadcastReceiver对象
receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
}
try {
receiver.setPendingResult(data);
//调用BroadcastReceiver的onReceive方法
receiver.onReceive(context.getReceiverRestrictedContext(),
data.intent);
}
if (receiver.getPendingResult() != null) {
//这个方法会触发下一个广播的处理,一个接着一个。
data.finish();
}
}
这样静态广播的处理流程也分析完了