写点什么

动态广播发送流程

作者:北洋
  • 2022 年 7 月 12 日
  • 本文字数:946 字

    阅读完需:约 3 分钟

广播发送流程

广播的发送者将广播发送到 ActivityManagerService,ActivityManagerService 接收到这个广播以后,就会在自己的注册中心查看有哪些广播接收器订阅了该广播,然后把这个广播逐一发送到这些广播接收器中,但是 ActivityManagerService 并不等待广播接收器处理这些广播就返回了,因此,广播的发送和处理是异步的。概括来说,广播的发送路径就是从发送者到 ActivityManagerService,再从 ActivityManagerService 到接收者,这中间的两个过程都是通过 Binder 进程间通信机制来完成的


1.在 Activity 中发送广播,sendBroadCast 方法其实是调用了 ContextWrapper 的 sendBroadcast 方法,ContextWrapper 类中的 sendBroadcast 方法,其实也是调用了 ContextImpl 的 sendBroadcast 方法这里的 resolvedType 表示这个 Intent 的 MIME 类型


  1. 这个方法中,通过进程间通信的的方式,调用了 system_server 进程的 ActivityManagerService 的 broadcastIntent 方法

在里面调用了 broadcastIntentLocked 方法,拆开进行分析:

3. 首先对 Intent 进行了处理,如果 broadCastReceiver 所在进程死亡那么将不会收到该广播


  1. 如果广播没有指定特性的接受者的话那么会调用到 mReceiverResolver.queryIntent()这个方法中,在上面注册的时候 BroadcastFilter 实例保存在了 ActivityManagerService 的成员变量 mReceiverResolver 中,这个 BroadcastFilter 实例包含了我们所注册的广播接收器,这里就通过 mReceiverResolver.queryIntent 函数将这个 BroadcastFilter 实例取回来。由于注册一个广播类型的接收器可能有多个,所以这里把所有符合条件的的 BroadcastFilter 实例放在一个 List 中,然后返回来。


  1. 这里是查看一下这个 intent 的 Intent.FLAG_RECEIVER_REPLACE_PENDING 位有没有设置,如果设置了的话,AMS 就会在当前的系统中查看有没有相同的 intent 还未被处理,如果有的话,就有当前这个新的 intent 来替换旧的 intent。


  1. 这个 if 语句首先创建一个广播记录块 BroadcastRecord,里面记录了这个广播是由谁发出的以及要发给谁等相关信息。由于前面得到的 replacePending 变量为 false,这里得到的 replaced 变量的值也为 false,于是执行下面的 if 语句,没有替换时,才需要将新的广播加入到 BroadcastQueue.mParallelBroadcasts 队列中,等待进一步处理;进一步处理的操作由函数 scheduleBroadcastsLocked 进行。处理完成之后会把 NR 重置



用户头像

北洋

关注

Android开发 2021.05.25 加入

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

评论

发布
暂无评论
动态广播发送流程_android_北洋_InfoQ写作社区