Android系统广播(1)–动态注册流程
1.基础
1.Android中的广播是一种跨进程通信机制。开发者需要注册接收器并指明接受条件,当有广播发出时符合该条件,该接收器就会收到广播回调其onReceive()方法。
2.广播的注册有两种方式:
动态注册:一般是在Activity中注册,新建子类继承实现BroadcastReceiver并指明条件IntentFilter,同时需要在Activity销毁时反注册。
静态注册:直接在manifest指明receiver和匹配的intentfilter。
区别:静态广播可以指定多进程属性。如果发送广播到静态接收器此时进程未启动,会在满足条件下启动指定的进程后在分发给静态接收器。
3.广播的类型:
无序广播:发送的广播没有顺序限制。直接遍历发出。
有序广播:发送的有序广播,需要根据接收器优先级依次发给不同接收器。并且只有一次发送结束才会开启下一次发送。
粘性广播:已经过时不建议使用。
2.广播动态注册过程
如下图:
动态广播一般是在Activity中注册调用regeisterReceiver()中传入实例和条件IntentFilter。在Activity销毁是unRegister()反注册。该注册方法真正实现在ContextImpl中。主要过程:
一、首先所有的registerReceiver()最后都是调用到registerReceiverInternal()传入的参数含义为:
receiver:开发者提供的广播接收器对象
filter:该接收器对应的接受条件
broadcastPermission:对广播发送方权限限制,只有满足该权限的广播才能被接受到。
schedluer:不指定该对象接受到广播后的onReceive()回调在主线程,指定之后在对应线程中。
1.在该函数内部,首先判断传入scheduler是否为空设置到正确值。
2.接着调用mPackageInfo.getReceiverDispatcher()获取一个IIntentReceiver对象。
在该函数中内部构造ReceiverDispatcher对象rd并保存,该对象负责客户端进程的广播分发。
函数返回rd对应的IIntentReceiver对象,该对象传入AMS中负责接受到新广播后回调通知客户端。
3.接下来就是回调AMS中的registerReceiver()传入之前的参数等。
二、AMS端的registerReceiver()函数中。
1.首先获取传入IntentFilter中的Action迭代器。接着遍历所有的Action查找其对应的粘性广播List。
2.接着从mRegisteredReceivers中获取传入的Broadcast对应的ReceiverList对象。ReceiverList对象与广播接收器一一对应,但是一个接收器可以接受多个广播(取决于注册给这个接收器的IntentFilter的个数)。ReceiverList内部存储这个接收器对应的BroadcastFilter对象。这个BroadcastFilter是AMS端的对象对应于IntentFilter。
一个BroadcastReceiver=多个IntentFilter=一个ReceiverList=多个BroadcastFilter
mRegisteredReceivers维护所有ReceiverList,mReceiverResolver维护所有BroadcastFilter
3.保存好对应的数据结构开始首先处理allSticky对应的粘性广播intent
遍历allSticky内部所有的intent即准备发送给接收器的intent。获取正确的BroadcastQueue,新建对应BroadcastRecord然后放入队列中,最后执行发送。
新建的BroadcastRecord传入了需要发送的intent还有接受者receivers。即知道发送的目的地和需要发送的intent。
以上就是广播的动态注册。
简单总结:
一、通过ContextImpl中实现具体注册逻辑,在客户端进程这里需要新建ReceiverDispatcher对象负责分发广播,同时传给AMS其对应的IIntentReceiver供回调。
二、在AMS中首先需要获取注册的IntentFilter是否对应已存在粘性广播,接着处理ReceiverList、BroadcastFilter、mRegisteredReceivers、mReceiverResolver等数据结构的保存创建等。对应关于如上。最后就是将查找到的粘性广播分发给对应的接收器。