Android Broadcast 详解
一、BroadcastReceiver是什么
BroadcastReceiver是 Android 四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),本质上是一种发布-订阅模式的通信机制:
- 发送方 :通过
sendBroadcast() 发送 Intent
- 接收方 :通过
BroadcastReceiver 的 onReceive() 接收并处理
广播可以实现:
- 应用内部组件通信
- 跨应用通信(系统广播、自定义广播)
- 系统事件监听(开机、网络变化、电量变化等)
二、广播的类型与区别
1. 按注册方式分类
| 类型 |
注册方式 |
生命周期 |
特点 |
| 静态广播 |
AndroidManifest.xml 中 <receiver> 标签 |
应用未运行也能接收 |
系统级事件、开机启动 |
| 动态广播 |
代码中 registerReceiver() |
随注册组件生命周期 |
灵活控制、性能更好 |
2. 按发送方式分类
| 类型 |
发送方法 |
特点 |
安全性 |
| 普通广播 |
sendBroadcast() |
异步、无序、同时发送给所有接收者 |
低,可被任意应用接收 |
| 有序广播 |
sendOrderedBroadcast() |
同步、按优先级顺序传递,可拦截/修改 |
中等 |
| 本地广播 |
LocalBroadcastManager.sendBroadcast() |
仅应用内部通信,效率更高 |
高(已废弃) |
3. 按发送范围分类
| 类型 |
说明 |
使用场景 |
| 系统广播 |
Android 系统发送(如开机、网络变化) |
监听系统状态变化 |
| 自定义广播 |
应用自己发送 |
应用内部/跨应用通信 |
三、核心原理
发送与接收流程
发送方
↓
Context.sendBroadcast(Intent)
↓
AMS (ActivityManagerService)
↓
遍历所有已注册的 BroadcastReceiver
↓
┌─────────────────┐
│ 静态广播 │ → 通过 PackageManager 解析 Manifest
│ 动态广播 │ → 通过 AMS 维护的 Receiver 列表
└─────────────────┘
↓
匹配 IntentFilter(action、category、data 等)
↓
创建 BroadcastReceiver 实例
↓
调用 onReceive(Context, Intent) [主线程]
↓
onReceive 执行完毕 → 销毁 Receiver 实例
关键原理点
- Receiver 是临时实例 :每次广播到达时,系统会创建新的
BroadcastReceiver 实例,执行完 onReceive() 后立即销毁
- onReceive 在主线程执行:耗时操作会导致 ANR(10 秒超时)
- AMS 统一管理 :所有广播路由都经过
ActivityManagerService
四、使用示例
1. 静态广播(Manifest 注册)
<!-- AndroidManifest.xml -->
<receiver android:name=".BootReceiver"
android:exported="true"> <!-- exported=true 允许跨应用接收 -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- 自定义广播 -->
<receiver android:name=".MyReceiver"
android:exported="false"> <!-- 仅应用内部 -->
<intent-filter>
<action android:name="com.example.ACTION_CUSTOM" />
</intent-filter>
</receiver>
// 接收器实现
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
// 开机启动逻辑
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
}
}
2. 动态广播(代码注册)
public class MainActivity extends AppCompatActivity {
private MyReceiver receiver;
private IntentFilter filter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receiver = new MyReceiver();
filter = new IntentFilter();
filter.addAction("com.example.ACTION_CUSTOM");
filter.addAction(Intent.ACTION_SCREEN_ON);
// 注册
registerReceiver(receiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 必须注销,否则内存泄漏
unregisterReceiver(receiver);
}
// 发送广播
public void sendCustomBroadcast() {
Intent intent = new Intent("com.example.ACTION_CUSTOM");
intent.putExtra("data", "hello");
sendBroadcast(intent);
}
}
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("com.example.ACTION_CUSTOM".equals(action)) {
String data = intent.getStringExtra("data");
Log.d("MyReceiver", "收到: " + data);
}
}
}
3. 有序广播
// 发送有序广播
public void sendOrderedBroadcast() {
Intent intent = new Intent("com.example.ACTION_ORDERED");
sendOrderedBroadcast(intent, null); // 第二个参数是权限
}
<!-- 接收器设置优先级 -->
<receiver android:name=".HighPriorityReceiver">
<intent-filter android:priority="100"> <!-- 优先级越高越先收到 -->
<action android:name="com.example.ACTION_ORDERED" />
</intent-filter>
</receiver>
<receiver android:name=".LowPriorityReceiver">
<intent-filter android:priority="1">
<action android:name="com.example.ACTION_ORDERED" />
</intent-filter>
</receiver>
// 高优先级接收器可以拦截或修改广播
public class HighPriorityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 修改结果数据
setResultData("modified_data");
// 拦截广播,不再传递给低优先级接收器
abortBroadcast();
}
}
4. 本地广播(已废弃,了解即可)
// LocalBroadcastManager 已废弃,建议使用 LiveData / Flow 替代
// 或直接使用 exported=false 的广播
五、系统常用广播
| 广播 Action |
说明 |
权限要求 |
ACTION_BOOT_COMPLETED |
开机完成 |
RECEIVE_BOOT_COMPLETED |
ACTION_SCREEN_ON/OFF |
屏幕亮/灭 |
无 |
ACTION_BATTERY_CHANGED |
电量变化 |
无(粘性广播) |
ACTION_CONNECTIVITY_CHANGE |
网络变化 |
ACCESS_NETWORK_STATE |
ACTION_PACKAGE_ADDED/REMOVED |
应用安装/卸载 |
无 |
ACTION_TIME_TICK |
每分钟触发 |
无 |
六、注意事项
1. ANR 风险(最重要)
// ❌ 错误:onReceive 中做耗时操作
@Override
public void onReceive(Context context, Intent intent) {
// 超过 10 秒就会 ANR!
downloadLargeFile();
}
// ✅ 正确:使用 goAsync() 或启动 Service
@Override
public void onReceive(Context context, Intent intent) {
final PendingResult pendingResult = goAsync();
new Thread(() -> {
try {
downloadLargeFile();
} finally {
pendingResult.finish(); // 必须调用!
}
}).start();
}
// ✅ 更推荐:启动 Service 或 WorkManager
@Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
2. 内存泄漏
// ❌ 错误:匿名内部类持有 Activity 引用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 匿名内部类隐式持有 MainActivity 引用
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 如果 Activity 已销毁但 Receiver 未注销,泄漏
}
}, new IntentFilter("ACTION"));
}
}
// ✅ 正确:使用成员变量 + 成对注册/注销
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receiver = new MyReceiver();
registerReceiver(receiver, new IntentFilter("ACTION"));
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver); // 必须注销!
}
}
3. Android 8.0+ 后台限制
// ⚠️ Android 8.0 (API 26) 开始,大部分隐式广播无法通过静态注册接收
// 以下广播仍支持静态注册:
// - 开机完成 (BOOT_COMPLETED)
// - 应用安装/卸载 (PACKAGE_ADDED/REMOVED)
// - 时区变化 (TIMEZONE_CHANGED)
// - 语言变化 (LOCALE_CHANGED)
// ❌ 以下广播不再支持静态注册:
// - 网络变化 (CONNECTIVITY_CHANGE)
// - 屏幕亮灭 (SCREEN_ON/OFF)
// - 电量变化 (BATTERY_CHANGED)
// ✅ 解决方案:改用动态注册
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(networkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
4. 安全性
// ❌ 错误:exported=true 且无权限控制,任意应用可发送/接收
<receiver android:name=".MyReceiver" android:exported="true">
<intent-filter>
<action android:name="com.example.ACTION" />
</intent-filter>
</receiver>
<!-- ✅ 正确:自定义权限控制 -->
<!-- 1. 定义权限(发送方和接收方都要声明) -->
<permission android:name="com.example.permission.RECEIVE_BROADCAST"
android:protectionLevel="signature" />
<!-- 2. 发送方声明权限 -->
<uses-permission android:name="com.example.permission.RECEIVE_BROADCAST" />
<!-- 3. 接收方要求权限 -->
<receiver android:name=".MyReceiver"
android:permission="com.example.permission.RECEIVE_BROADCAST"
android:exported="true">
<intent-filter>
<action android:name="com.example.ACTION" />
</intent-filter>
</receiver>
// 4. 发送时指定权限
sendBroadcast(intent, "com.example.permission.RECEIVE_BROADCAST");
<!-- ✅ 更推荐:使用 exported=false 限制应用内部 -->
<receiver android:name=".InternalReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.ACTION_INTERNAL" />
</intent-filter>
</receiver>
5. 跨进程通信
// 跨应用广播需要 exported=true
// 或使用显式 Intent 指定目标包名
Intent intent = new Intent();
intent.setAction("com.example.ACTION");
intent.setPackage("com.target.app"); // 指定接收方包名
sendBroadcast(intent);
6. 粘性广播(已废弃)
// ⚠️ sendStickyBroadcast() 已废弃,不要使用
// 替代方案:使用 LiveData、SharedPreferences 或 ContentProvider
7. 本地广播替代方案
// LocalBroadcastManager 已废弃,推荐使用:
// 1. LiveData / MutableLiveData(应用内通信)
// 2. Kotlin Flow / SharedFlow
// 3. EventBus(第三方库)
// 4. RxBus(RxJava)
// ✅ 示例:使用 LiveData
class EventBus {
private val _events = MutableLiveData<Event>()
val events: LiveData<Event> = _events
fun post(event: Event) {
_events.value = event
}
}
七、总结
| 问题 |
答案 |
| BroadcastReceiver是什么? |
Android 发布-订阅模式的组件间通信机制 |
| 核心原理? |
通过 AMS 路由,匹配 IntentFilter,在主线程回调 onReceive |
| 静态 vs 动态? |
静态:应用未运行也能接收;动态:灵活、性能更好、需手动注销 |
| 普通 vs 有序? |
普通:异步无序;有序:同步按优先级,可拦截 |
| 主要风险? |
ANR(10秒限制)、内存泄漏、Android 8.0+ 后台限制 |
| 现代替代方案? |
应用内通信用 LiveData/Flow,跨组件用 WorkManager/Service |
一句话总结:BroadcastReceiver是 Android 的"全局事件总线",适合系统事件监听和跨应用通信;应用内部通信优先使用 LiveData/Flow,避免广播带来的性能和安全问题。