ActivityManagerService广播怎么注册与发送
导读:本文共12392.5字符,通常情况下阅读需要41分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 注册广播接收器广播接收器可以分为动态和静态,静态广播接收器就是在 AndroidManifest.xml 中注册的,而动态的广播接收器是在代码中通过 Context#registerReceiver() 注册的。静态广播接收器,在发送广播时,服务端会从 PKMS 中收集,而动态的广播接收器,需要接收方发送给服务端。因此,下面只分析动态广播接收器的注册过程//Co... ...
目录
(为您整理了一些要点),点击可以直达。广播接收器可以分为动态和静态,静态广播接收器就是在 AndroidManifest.xml 中注册的,而动态的广播接收器是在代码中通过 Context#registerReceiver() 注册的。
静态广播接收器,在发送广播时,服务端会从 PKMS 中收集,而动态的广播接收器,需要接收方发送给服务端。因此,下面只分析动态广播接收器的注册过程
广播接收方注册接收器的过程如下
获取 IIntentReceiver 对象,它是一个 Binder 对象,其实就是一个 Binder 回调。
向服务端 AMS 注册 IIntentReceiver 对象,用于接收广播消息的回调。
当接收方收到来自服务端的广播消息后,会通过 IIntentReceiver 对象,调用 BroadcastReceiver#onReceive() 来处理广播。
现在来看下服务端是如何完成广播接收器的注册工作的
服务端对于动态注册的广播接收器的处理过程如下
使用 mRegisteredReceivers 建立客户端与服务端的广播接收器的映射。ReceiverList 代表服务端的广播接收器,IIntentReceiver 代表客户端的广播接收器。
使用客户端的 IntentFilter , 创建服务端的广播过滤器 BroadcastFilter,并保存到 mReceiverResolver。注意,这一步中,ReceiverList 和 BroadcastFilter 互相保存了引用。
这些数据结构都是相互关联的,有何种用意呢?当发送方发送广播到 AMS,AMS 会使用 mReceiverResolver 匹配 BroadcastFilter,BroadcastFilter 找到 ReceiverList,ReceiverList 找到 IIntentReceiver,IIntentReceiver 发送广播给接收方。
另外,由于 sticky 广播是会被缓存的,当注册 sticky 广播的接收器时,有以下两种处理方式
如果注册的广播接收器为 null,那么会返回最近的一次广播数据给接收方。
如果注册的广播接收器不为null,那么会把匹配到的 sticky 广播发送给接收方的广播接收器,也就是会调用 BroadcastReceiver#onReceive()。
发送广播的方法,有多个重载方法,挑选一个最简单的来分析,如下
这段代码设计的并不是很好,很多细节都杂糅到一个方法中。对于一些细节,我进行了详细的注释,有兴趣的读者可以自行研究,而本文只关心发送广播的主要流程。
我不打算按照代码的逻辑来讲解流程,我自己总结了一套流程。
对于非有序广播(包括 sticky 广播),发送流程如下
把广播“并行”地发送给动态广播接收器。
把广播“串行”地发送给静态广播接收器。
为何要把非有序广播(包括 sticky 广播)优先发送给动态接收器?最简单的理由就是,不需要先拉起进程!因为"快”,所以先发送。
对于有序广播,发送的流程如下
按照广播的优先级,从高到低,把动态和静态广播接收器,合并到一起。
“串行”发送广播给所有的接收器。
有序广播,为何不先发送给动态接收器呢?因为它强调一个“有序”,所以要根据优先级来发送。
对于 sticky 广播,由于它的特性,是需要对它的广播 Intent 进行缓存的。根据前面注册广播接收器的分析,当注册的广播接收器匹配到缓存的 sticky 广播 Intent,那么会立即返回数据给接收方,无论是通过函数的返回值,还是直接调用 BroadcastReceiver#onReceive()。
ActivityManagerService广播怎么注册与发送的详细内容,希望对您有所帮助,信息来源于网络。