05 Broadcast 源码机制与面试要点

基于原 PDF 修订、联网校对并补充缺失内容

1. 系统广播的大致链路

从源码角度看,系统广播不是“直接调用所有 receiver”。发送、注册、查询匹配、排队和进程调度都经过系统服务协调。面试时可以用下面的链路表达,不需要死背每个类名。

  1. 接收方注册:Manifest receiver 由 PackageManager 解析安装包得到;动态 receiver 通过 registerReceiver 走 Binder 注册到系统服务。
  2. 发送方发送:sendBroadcast/sendOrderedBroadcast 通过 Binder 把 Intent 交给 ActivityManagerService/ActivityManager 相关服务。
  3. 系统匹配:根据 action、data、category、package、component、permission、用户等条件匹配 receiver。
  4. 广播入队:普通广播可并行/异步调度;有序广播按顺序串行推进。
  5. 进程处理:如果目标进程不存在且允许唤起,系统启动应用进程;最终通过主线程 Handler 调用 BroadcastReceiver.onReceive。
  6. 生命周期结束:onReceive 返回后,receiver 对象就不再活跃;如果进程没有其他重要组件,系统可以回收进程。

2. 修正原 PDF 的源码表述

原 PDF 表述 问题 修正说法
自定义 BroadcastReceiver,并且重写 onReceiver() 方法名错误。 应为重写 onReceive(Context, Intent)。
AMS 将广播发送到相应 BroadcastReceiver(一般情况下是 Activity)的消息队列中 BroadcastReceiver 不是 Activity;“一般情况下是 Activity”不准确。 系统把消息分发到目标应用进程的主线程/ReceiverDispatcher,再回调 receiver.onReceive。
本地广播只在 app 内传播 对 LocalBroadcastManager 来说更准确是同一进程内的应用级事件总线。 它已废弃;仅作为历史实现理解。
静态注册一定能在程序未启动时收到广播 忽略 Android 8.0 后隐式广播限制。 manifest receiver 是入口之一,但是否能唤起取决于广播类型、targetSdkVersion、权限、显式/隐式等。

3. 普通广播、有序广播、粘性广播的机制差异

类型 调度特点 结果传递 是否推荐
普通广播 匹配后分发给接收者,不提供可依赖顺序 系统事件和简单通知可用,但内部事件可考虑 Flow/LiveData。
有序广播 按优先级/顺序逐个分发 可 setResult/abort 仅在确实需要顺序和结果传递时使用。
Sticky Broadcast 广播结束后缓存 Intent,后注册 receiver 可能收到历史值 可被重放/篡改风险 不推荐,避免新业务使用。

4. LocalBroadcastManager 历史实现

LocalBroadcastManager 曾经常被用于应用内事件分发。它不经过系统 AMS,不走跨进程 Binder 广播路径,而是在应用进程内维护 receiver/action 映射,并通过 Handler 把待分发事件投递回主线程。

  • mReceivers:记录 receiver 对应的过滤器。
  • mActions:记录 action 到 receiver 的映射。
  • mPendingBroadcasts:记录待投递广播。
  • 优点是进程内开销低;缺点是架构上像全局事件总线,类型不安全,已经废弃。

5. 面试题速记

问题 回答要点
Broadcast 有哪些注册方式? Manifest-declared 和 Context-registered;前者可作为系统入口但受版本限制,后者与 context 生命周期绑定。
有序广播和普通广播区别? 有序广播串行、可传递结果和中断;普通广播不保证顺序,不适合依赖结果链。
为什么 onReceive 不能做耗时任务? 通常在主线程执行,receiver 活跃期短,超时可能 ANR;返回后进程可能被回收。
Android 8.0 对广播有什么限制? target 26+ 不能在 manifest 中注册大多数隐式广播,除豁免项或显式发给应用。
Android 14 动态 receiver 要注意什么? target 34+ 一般要指定 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED。
LocalBroadcastManager 还能用吗? 历史项目可能见到,但已废弃;新代码用 LiveData/Flow/Reactive streams 等观察者方案。

6. 一句话总结

Broadcast 是系统级低耦合通知机制,不是通用事件总线,也不是后台保活工具。现代 Android 开发中,使用 Broadcast 要优先考虑生命周期、后台限制和安全边界。

参考资料