【私人备忘录】Android P ActivityManagerService(四)BroadcastReceiver的工作过程

静态注册的广播是有PMS完成注册的,不在AMS系列中讨论,只看动态注册。

一、注册广播代码流程

ContextWrapper.java
registerReceiver();Activity.java调用的是爷爷类ContextWrapper.java的registerReceiver()
ContextImpl.java
registerReceiver() → registerReceiverInternal(ActivityManager.getService().registerReceiver())
ActivityManagerService.java
registerReceiver()

备注:
1、ContextImpl.registerReceiverInternal()中用mPackageInfo.getReceiverDispatcher获取了IIntentReceiver,IIntentReceiver是Binder接口,是LoadedApk.ReceiverDispatcher.InnerReceiver,看着和Service的有点像,原理是类似的。这玩样儿用于进程间通讯的,所以不用BroadcastReceiver而使用IIntentReceiver。
2、ActivityManagerService.registerReceiver()主要工作:
    2.1、存储远程的IIntentReceiver对象:mRegisteredReceivers.put(receiver.asBinder(), rl);
    2.2、存储IntentFilter对象:BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission, callingUid, userId, instantApp, visibleToInstantApps);mReceiverResolver.addFilter(bf);
3、每一个应用都持有一个LoadedApk实例,LoadedApk实例中包含多个Context实例,每个Context实例可能创建了多个BroadcastReceiver实例,每个BroadcastReceiver实例在动态注册的时候都会生成一个对应的ReceiverDispatcher实例,每个ReceiverDispatcher实例内部又会由InnerReceiver类生成一个IIntentReceiver实例。这个IIntentReceiver实例在动态注册BroadcastReceiver的时候会被传递给AMS,AMS会为每个IIntentReceiver实例创建一个ReceiverList实例,每个ReceiverList实例中保存了多个BroadcastFilter实例,而这个BroadcastFilter实例里面包含了具体的IntentFilter和ReceiverList等相关信息。

二、广播的收发代码流程

ContextWrapper.java
sendBroadcast();Activity.java调用的是爷爷类ContextWrapper.java的sendBroadcast()
ContextImpl.java
sendBroadcast(ActivityManager.getService().broadcastIntent())
ActivityManagerService.java
broadcastIntent() → broadcastIntentLocked(queue.scheduleBroadcastsLocked())
BroadcastQueue.java
scheduleBroadcastsLocked(mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this))) → BroadcastHandler.handleMessage(case BROADCAST_INTENT_MSG) → processNextBroadcast() → processNextBroadcastLocked() → deliverToRegisteredReceiverLocked() → performReceiveLocked(app.thread.scheduleRegisteredReceiver())
ActivityThread.java
ApplicationThread.scheduleRegisteredReceiver(receiver.performReceive())
LoadedApk.java
ReceiverDispatcher.performReceive(mActivityThread.post(args.getRunnable())) → Args.getRunnable()
BroadcastReceiver.java
onReceive()

备注:
1、ActivityManagerService.broadcastIntentLocked()刚开始地方有:intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);代码也有注释,默认情况下广播不会发送给已经停止的应用,如果想发给已经停止的应用,可以加上Intent.FLAG_INCLUDE_STOPPED_PACKAGES的flag。
2、ActivityManagerService.broadcastIntentLocked()贼长,主要是根据Filter查找满足条件的接受者并添加到BroadcastQueue中。
    2.1、receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);静态注册广播接收者
    2.2、registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, userId);动态注册的广播接收者
    2.3、receivers.add(registeredReceivers.get(ir));动态注册的registeredReceivers,全部合并到receivers赋值给BroadcastRecord,再统一按串行方式处理:queue.enqueueOrderedBroadcastLocked(r);queue.scheduleBroadcastsLocked();
3、BroadcastQueue.processNextBroadcastLocked()贼长,这里只主要看下//First, deliver any non-serialized broadcasts right away.无需广播处理,走了一波deliverToRegisteredReceiverLocked()。
4、Args.getRunnable()主要代码有:final BroadcastReceiver receiver = mReceiver;receiver.setPendingResult(this);receiver.onReceive(mContext, intent);这里onReceive已经被执行了,因为是mActivityThread.post执行的,所以是在主线程执行的。

三、关系图

类关系图

流程关系图

备注:
1、动态注册过程可理解为建立LoadedApk、Context、BroadcastReceiver和ReceiverDispatcher的映射关系;建立ReceiverList和BroadcastFilter的映射关系。两个映射关系共同持有同一个IIntentReceiver。
2、广播的收发AMS根据Context广播的Intent信息对照映射关系表从BroadcastFilter开始,反向一层一层找到与之对应的BroadcastReceiver,最终完成BroadcastReceiver.OnReceive的调用,把Intent传递给对应的BroadcastReceiver。 

发布了15 篇原创文章 · 获赞 107 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/llleahdizon/article/details/90171692