Android动态广播注册收发原理
一、动态广播的注册流程
1. 注册方式
动态广播通过代码调用 Context.registerReceiver()
方法实现,需显式指定 IntentFilter
和接收器实例:
// 示例:在 Activity 中注册监听网络变化的广播
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(networkChangeReceiver, filter);
- 生命周期绑定:动态注册的接收器仅在注册期间有效(如 Activity 处于
onResume()
状态时),需在onPause()
或onDestroy()
中调用unregisterReceiver()
释放资源。 - 优先级控制:通过
IntentFilter.setPriority(int)
设置接收器优先级,影响有序广播的分发顺序。
2. 系统级处理
- AMS 注册:调用
registerReceiver()
时,系统会通过 Binder 调用 AMS 的registerReceiver()
方法,将接收器加入ReceiverDispatcher
的监听列表。 - 进程绑定:动态接收器与宿主进程(如 Activity 所在进程)强关联,进程终止后自动失效。
二、广播的发送与接收原理
1. 发送广播
- Intent 封装:通过
Intent
指定广播动作(action
)、数据(extras
)及目标接收器(setPackage()
)。 - 发送方式:
- 无序广播:
sendBroadcast()
,所有匹配接收器并行处理。 - 有序广播:
sendOrderedBroadcast()
,按优先级顺序处理,支持终止传播(abortBroadcast()
)。
- 无序广播:
2. 接收流程
- AMS 分发:发送广播后,AMS 根据
IntentFilter
匹配动态注册的接收器列表。 - 消息队列调度:AMS 将广播封装为
BroadcastRecord
,加入BroadcastQueue
队列。 - 线程执行:通过
Handler
将onReceive()
调度至宿主进程的主线程执行(避免跨线程问题)。
3. 数据传递
- Intent 携带数据:发送方可通过
putExtra()
附加数据,接收方从Intent
中提取。 - 跨进程通信:若接收器与发送方进程不同,AMS 通过 Binder 机制跨进程传递
Intent
。
三、系统级调度机制
1. AMS 的核心作用
- 广播队列管理:AMS 维护全局的
BroadcastQueue
,按时间顺序或优先级调度广播。 - 权限校验:检查发送方与接收方的权限声明(如
android:permission
),防止未授权广播。 - 进程状态维护:若接收器所在进程未启动,AMS 会触发进程启动(仅限静态注册,动态注册需宿主进程存活)。
2. 有序广播的特殊处理
- 优先级队列:接收器按
android:priority
排序,高优先级者先处理。 - 结果反馈:接收器可通过
setResultExtras()
传递数据给后续接收器,或调用abortBroadcast()
终止传播。
3. 性能优化
- 批量处理:同一时间点到达的广播可能合并处理,减少上下文切换。
- 延迟分发:对耗时操作(如网络请求)自动延迟至
onReceive()
返回后执行。