写点什么

动态注册广播流程源码解析

作者:北洋
  • 2022 年 7 月 11 日
  • 本文字数:1307 字

    阅读完需:约 4 分钟

LockedApk 中有一个 mReceivers 对象,以 Context 为 key, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>为 value。每一个 Context 都有一个这样的 hashmap,key 就是 receiver,value 是 ReceiverDispatcher。每一个 receiver 都对应一个 ReceiverDispatcher。


总结:就是创建了一个 RD 对象(ReceiverDispatcher 为了之后 AMS 和收到广播之后远程调用和可以通过 handler 插入到消息队列中去处理),这个是在 LockedApk 中创建的,首先 LockedApk 有一个 mReceivers 属性,这个属性里面存放的是 key 是 Context,value 是这个上下文中所有注册了 receiver 的集合,key 是 receiver,value 是 RD,这个 RD 构造方法里面保存了 hander 以便收到消息之后添加到消息队列中,RD 里面有一个静态类 InnerReceiver 继承自这个类 IIntentReceiver.Stub 是个代理所以可以通过他进行 AMS 到 Rd 中的通信 3.在完成了 mPackageInfo.getReceiverDispatcher()创建 InnerReceiver 对象后,继续调用了 AMS 的 registerReceiver 方法




拆开进行分析:(1)首先获取注册的进程信息



(2)接着迭代 filter 的 actions 进行调用 getStickLocked 函数查找一下有没有对应的 sticky intent 列表存在。sticky intent 列表:我们在最后一次调用 sendStickyBroadcast 函数来发送某个 Action 类型的广播时,系统会把代表这个广播的 Intent 保存下来,这样,后来调用 registerReceiver 来注册相同 Action 类型的广播接收器,就会得到这个最后发出的广播。这就是为什么叫做 Sticky Intent 了,这个最后发出的广播虽然被处理完了,但是仍然被粘住在 ActivityManagerService 中,以便下一个注册相应 Action 类型的广播接收器还能继承处理。



(3)接下来把广播接收器 receiver 保存一个 ReceiverList 列表中,这个列表的宿主进程是 rl.app,在 ActivityManagerService 中,用一个进程记录块来表示这个应用程序进程,它里面有一个列表 receivers,专门用来保存这个进程注册的广播接收器。接着,又把这个 ReceiverList 列表以 receiver 为 Key 值保存在 ActivityManagerService 的成员变量 mRegisteredReceivers 中,这些都是为了方便在收到广播时,快速找到对应的广播接收器的。



(4)上面只是把广播接收器 receiver 保存起来了,但是还没有把它和 filter 关联起来,这里就创建一个 BroadcastFilter 来把广播接收器列表 rl 和 filter 关联起来,然后保存在 ActivityManagerService 中的成员变量 mReceiverResolver 中去。



这个方法内部,首先获取了最后一个粘性消息(如果有多个 action,取最后一个 action 的最后一次粘性消息,在最后进行返回这个粘性消息。如果注册的 receiver 传入的是 null 只传入了 actions,那么会直接返回这个最后的粘性消息),接着通过 AMS 的本地集合变量 mRegisteredReceivers 通过 receiver(key)获取 rl(ReceiverList 就是 value)获取不到进行创建 rl,rl 构造方法中传入了进程记录块(callerApp)和 Binder 调用者的 uid 和 pid,还有 receiver。创建完后之后把当前 rl 添加到 rl 的进程记录块里面的 receivers 中,然后将 receiver 为 key,rl 为 value 保存添加到 mRegisteredReceivers 中;receivers 保存完之后开始保存 filter,创建一个 BroadcastFilter(将 filter 和 rl 传入),接着把 bf 添加到 rl 中,并把 bf 添加到 AMS 本地集合 mReceiverResolver 中。这样注册过程就完成了。

用户头像

北洋

关注

Android开发 2021.05.25 加入

记录Android学习之路 分享读书心得体会~

评论

发布
暂无评论
动态注册广播流程源码解析_Andriod_北洋_InfoQ写作社区