BroadcastReceiver
外观
- BroadcastReceiver
BroadcastReceiver(广播接收器)是Android系统中的一种组件,用于监听和响应系统或应用发出的广播消息。它允许应用程序在特定事件发生时执行代码,而无需保持持续运行状态。
- 概述
BroadcastReceiver是Android四大组件之一(其他三个是Activity、Service和ContentProvider)。它工作在发布-订阅模式中,可以接收来自系统或其他应用的广播消息。
广播分为两种类型:
- **普通广播(Normal broadcasts)** - 完全异步的广播,所有接收器几乎同时接收
- **有序广播(Ordered broadcasts)** - 同步执行的广播,一次只传递给一个接收器
- 工作原理
- 实现方式
- 静态注册
在AndroidManifest.xml中声明接收器:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
- 动态注册
在代码中动态注册接收器:
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 处理广播
}
};
IntentFilter filter = new IntentFilter("com.example.MY_ACTION");
registerReceiver(receiver, filter);
- 常见系统广播
Android系统会发送多种广播,常见的有:
- `ACTION_BOOT_COMPLETED` - 系统启动完成
- `ACTION_BATTERY_LOW` - 电池电量低
- `ACTION_SCREEN_ON` - 屏幕点亮
- `ACTION_SCREEN_OFF` - 屏幕关闭
- `ACTION_AIRPLANE_MODE_CHANGED` - 飞行模式状态改变
- 自定义广播
应用可以发送自定义广播:
Intent intent = new Intent();
intent.setAction("com.example.MY_ACTION");
intent.putExtra("data", "Hello World!");
sendBroadcast(intent);
- 权限控制
广播可以设置权限来限制发送和接收:
<!-- 声明权限 -->
<permission android:name="com.example.MY_PERMISSION"/>
<!-- 发送带权限的广播 -->
sendBroadcast(intent, "com.example.MY_PERMISSION");
<!-- 接收带权限的广播 -->
<receiver android:name=".MyReceiver"
android:permission="com.example.MY_PERMISSION">
<intent-filter>
<action android:name="com.example.MY_ACTION"/>
</intent-filter>
</receiver>
- 最佳实践
1. **避免长时间操作**:`onReceive()`方法应在几秒内完成,否则可能导致ANR 2. **使用JobScheduler**:对于耗时任务,应使用JobScheduler 3. **及时注销**:动态注册的接收器应在不再需要时注销 4. **限制导出**:除非必要,应将`android:exported`设为false
- 实际应用示例
- 监听网络状态变化
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null
&& activeNetwork.isConnectedOrConnecting();
if (isConnected) {
Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show();
}
}
}
- 限制与替代方案
从Android 8.0(API 26)开始,系统对广播接收器施加了更多限制:
- 大多数静态注册的接收器无法接收隐式广播
- 建议使用JobScheduler或WorkManager替代部分广播功能
- 参见