跳转到内容

BroadcastReceiver

来自代码酷
  1. BroadcastReceiver

BroadcastReceiver(广播接收器)是Android系统中的一种组件,用于监听和响应系统或应用发出的广播消息。它允许应用程序在特定事件发生时执行代码,而无需保持持续运行状态。

    1. 概述

BroadcastReceiver是Android四大组件之一(其他三个是ActivityServiceContentProvider)。它工作在发布-订阅模式中,可以接收来自系统或其他应用的广播消息。

广播分为两种类型:

  • **普通广播(Normal broadcasts)** - 完全异步的广播,所有接收器几乎同时接收
  • **有序广播(Ordered broadcasts)** - 同步执行的广播,一次只传递给一个接收器
    1. 工作原理

graph LR A[广播发送者] -->|发送广播| B[Android系统] B -->|分发广播| C[BroadcastReceiver1] B -->|分发广播| D[BroadcastReceiver2] B -->|分发广播| E[...]

    1. 实现方式
      1. 静态注册

在AndroidManifest.xml中声明接收器:

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
      1. 动态注册

在代码中动态注册接收器:

BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理广播
    }
};

IntentFilter filter = new IntentFilter("com.example.MY_ACTION");
registerReceiver(receiver, filter);
    1. 常见系统广播

Android系统会发送多种广播,常见的有:

  • `ACTION_BOOT_COMPLETED` - 系统启动完成
  • `ACTION_BATTERY_LOW` - 电池电量低
  • `ACTION_SCREEN_ON` - 屏幕点亮
  • `ACTION_SCREEN_OFF` - 屏幕关闭
  • `ACTION_AIRPLANE_MODE_CHANGED` - 飞行模式状态改变
    1. 自定义广播

应用可以发送自定义广播:

Intent intent = new Intent();
intent.setAction("com.example.MY_ACTION");
intent.putExtra("data", "Hello World!");
sendBroadcast(intent);
    1. 权限控制

广播可以设置权限来限制发送和接收:

<!-- 声明权限 -->
<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. 最佳实践

1. **避免长时间操作**:`onReceive()`方法应在几秒内完成,否则可能导致ANR 2. **使用JobScheduler**:对于耗时任务,应使用JobScheduler 3. **及时注销**:动态注册的接收器应在不再需要时注销 4. **限制导出**:除非必要,应将`android:exported`设为false

    1. 实际应用示例
      1. 监听网络状态变化
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();
        }
    }
}
    1. 限制与替代方案

从Android 8.0(API 26)开始,系统对广播接收器施加了更多限制:

  • 大多数静态注册的接收器无法接收隐式广播
  • 建议使用JobSchedulerWorkManager替代部分广播功能
    1. 参见