7.4 KiB
7.4 KiB
BroadcastReceiver详解
目录
BroadcastReceiver类型
普通广播接收器
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");
// 处理数据
}
}
}
有序广播接收器
// 可以设置优先级和结果
public class OrderedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 处理广播
setResultCode(Activity.RESULT_OK);
setResultData("Result Data");
}
}
静态注册与动态注册
静态注册
<!-- AndroidManifest.xml -->
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
特点:
- 应用安装时注册
- 可以接收系统广播
- 应用未运行也能接收
- Android 8.0+ 限制静态注册
动态注册
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 处理广播
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.ACTION_CUSTOM");
registerReceiver(receiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
特点:
- 代码中注册
- 需要应用运行
- 必须手动注销
- 更灵活
有序广播与无序广播
无序广播
// 发送无序广播
Intent intent = new Intent("com.example.ACTION_BROADCAST");
intent.putExtra("data", "value");
sendBroadcast(intent);
// 所有接收器同时接收
// 无法中断广播
有序广播
// 发送有序广播
Intent intent = new Intent("com.example.ACTION_BROADCAST");
intent.putExtra("data", "value");
sendOrderedBroadcast(intent, null);
// 接收器按优先级接收
// 可以中断广播
优先级设置
<!-- AndroidManifest.xml -->
<receiver android:name=".MyReceiver">
<intent-filter android:priority="1000">
<action android:name="com.example.ACTION_BROADCAST" />
</intent-filter>
</receiver>
// 动态注册设置优先级
IntentFilter filter = new IntentFilter("com.example.ACTION_BROADCAST");
filter.setPriority(1000);
registerReceiver(receiver, filter);
中断广播
@Override
public void onReceive(Context context, Intent intent) {
// 中断广播
abortBroadcast();
// 设置结果
setResultCode(Activity.RESULT_OK);
setResultData("Result");
}
系统广播
常用系统广播
// 开机完成
Intent.ACTION_BOOT_COMPLETED
// 网络状态变化
ConnectivityManager.CONNECTIVITY_ACTION
// 电池状态变化
Intent.ACTION_BATTERY_CHANGED
// 屏幕开启/关闭
Intent.ACTION_SCREEN_ON
Intent.ACTION_SCREEN_OFF
// 应用安装/卸载
Intent.ACTION_PACKAGE_ADDED
Intent.ACTION_PACKAGE_REMOVED
// 时间变化
Intent.ACTION_TIME_TICK
Intent.ACTION_TIME_CHANGED
系统广播接收
// 接收开机广播
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);
}
}
}
自定义广播
发送自定义广播
// 发送无序广播
Intent intent = new Intent("com.example.ACTION_CUSTOM");
intent.putExtra("data", "value");
sendBroadcast(intent);
// 发送有序广播
sendOrderedBroadcast(intent, null);
// 发送本地广播(LocalBroadcastManager)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
接收自定义广播
// 静态注册
<receiver android:name=".CustomReceiver">
<intent-filter>
<action android:name="com.example.ACTION_CUSTOM" />
</intent-filter>
</receiver>
// 动态注册
IntentFilter filter = new IntentFilter("com.example.ACTION_CUSTOM");
registerReceiver(receiver, filter);
广播安全
安全措施
1. 限制广播接收
<!-- AndroidManifest.xml -->
<receiver
android:name=".MyReceiver"
android:exported="false"> <!-- 不允许其他应用发送 -->
<intent-filter>
<action android:name="com.example.ACTION_CUSTOM" />
</intent-filter>
</receiver>
2. 使用权限
<!-- 发送广播需要权限 -->
<uses-permission android:name="com.example.PERMISSION" />
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="com.example.ACTION_CUSTOM" />
</intent-filter>
</receiver>
<!-- 发送广播 -->
sendBroadcast(intent, "com.example.PERMISSION");
3. 使用本地广播
// LocalBroadcastManager:只能应用内接收
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
// 注册本地广播
LocalBroadcastManager.getInstance(this)
.registerReceiver(receiver, filter);
BroadcastReceiver最佳实践
1. 及时注销
@Override
protected void onDestroy() {
super.onDestroy();
if (receiver != null) {
unregisterReceiver(receiver);
}
}
2. 避免耗时操作
@Override
public void onReceive(Context context, Intent intent) {
// ❌ 错误:在 onReceive 中执行耗时操作
// doHeavyWork();
// ✅ 正确:启动 Service 执行耗时操作
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
3. 使用 LocalBroadcastManager
// 应用内通信使用本地广播
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
面试常见问题
Q1: 静态注册和动态注册的区别?
答案:
- 静态注册:AndroidManifest.xml 中注册,应用安装时注册,可以接收系统广播
- 动态注册:代码中注册,需要应用运行,必须手动注销
Q2: 有序广播和无序广播的区别?
答案:
- 无序广播:所有接收器同时接收,无法中断
- 有序广播:按优先级接收,可以中断
Q3: Android 8.0 对广播的限制?
答案:
- 限制静态注册大部分广播
- 推荐使用动态注册
- 使用 JobScheduler 或 WorkManager 替代
Q4: 广播安全措施?
答案:
- 设置
android:exported="false" - 使用权限保护
- 使用本地广播(LocalBroadcastManager)
最后更新:2024年