1. 注册广播:封装Binder对象到AMS
动态广播的注册核心在于将接收器与AMS(Activity Manager Service)建立跨进程通信通道,具体流程如下:
- Binder对象生成
当应用调用registerReceiver()
动态注册广播时,系统会通过LoadedApk
创建ReceiverDispatcher
对象,其内部封装了InnerReceiver
(继承自IIntentReceiver.Stub
的Binder接口)。该Binder对象作为跨进程通信的媒介,允许AMS向应用端回调广播事件。 - 注册到AMS
ReceiverDispatcher
的IIntentReceiver
对象通过Binder机制传递给AMS,AMS将其与IntentFilter
绑定并记录在mRegisteredReceivers
映射表中。此过程确保广播事件能通过Binder通道准确路由到目标应用。 - 生命周期管理
动态广播的注册与销毁需与组件(如Activity)生命周期同步。通常在onStart()
中注册,onStop()
中通过unregisterReceiver()
注销,防止内存泄漏。
2. 广播匹配与分发:Intent过滤与接收者查找
当广播发送时,AMS通过以下机制匹配接收者并分发:
- Intent匹配规则
AMS根据Intent
的Action、Data(URI与MIME类型)、Category三个要素与注册的IntentFilter
进行匹配。只有三者完全匹配的接收者才会被触发。 - 动态与静态接收者区分
动态接收者存储在AMS的mRegisteredReceivers
中,而静态接收者需通过PackageManager
查询AndroidManifest.xml
中的声明。动态接收者优先级高于静态接收者。 - 广播队列分类
匹配后的接收者根据广播类型(普通或有序)加入不同队列:- 普通广播(无序):存入
mParallelBroadcasts
队列,系统端并行分发。 - 有序广播:存入
mOrderedBroadcasts
队列,按优先级串行分发。
- 普通广播(无序):存入
3. 分发机制:系统端并行与应用端串行
- 系统端并行分发
普通广播通过BroadcastQueue.processNextBroadcast()
处理,遍历mParallelBroadcasts
队列,向所有动态接收者并行发送。每个接收者通过performReceiveLocked()
触发InnerReceiver
的Binder调用,将广播事件传递至应用进程的主线程消息队列。 - 应用端串行执行
应用主线程的Handler
依次处理消息队列中的广播事件,调用BroadcastReceiver.onReceive()
方法。由于onReceive()
在主线程执行,需避免耗时操作,否则会引发ANR(应用无响应)。 - 粘性广播的特殊处理
普通广播属于“一次性”事件,而粘性广播(如网络状态变化)会被AMS缓存,新注册的接收者可立即收到最后一次广播值。但自Android 8.0起,粘性广播的使用受限,推荐改用LocalBroadcastManager
。
关键设计要点
- 跨进程通信:Binder机制实现AMS与应用的高效通信,
IIntentReceiver
作为通信代理。 - 安全性控制:AMS通过权限验证(如
android:permission
)确保只有授权应用能接收特定广播。 - 性能优化:普通广播的并行分发减少延迟,而有序广播支持中断传播(通过
abortBroadcast()
)。
总结
动态广播的注册与分发机制体现了Android系统高效、解耦的设计理念:通过Binder实现跨进程通信,利用Intent匹配精准路由事件,结合系统端并行与应用端串行的分发策略平衡性能与稳定性。开发者需注意生命周期管理与主线程限制,以优化广播使用体验。