Android 广播接收器(Broadcast Receivers)(建议收藏)

Android 广播接收器(Broadcast Receivers) 入门指南

在 Android 开发中,你可能遇到过这样的场景:手机充电时自动弹出通知,Wi-Fi 连接状态变化时更新界面,或者闹钟响起时播放铃声。这些看似“自动触发”的行为背后,其实都依赖一个核心组件——Android 广播接收器(Broadcast Receivers)。它就像一个“监听器”,时刻守候在系统角落,一旦某个事件发生,它就能立刻响应。

对于初学者来说,广播接收器可能显得有些抽象。但别担心,它其实并不复杂。今天我们就用最接地气的方式,带你一步步掌握它的核心机制和实际用法。


什么是 Android 广播接收器?

Android 广播接收器是 Android 系统中用于接收和处理广播消息的组件。广播是一种系统级的事件通知机制,任何应用都可以发出广播,也可以注册接收特定广播。

你可以把广播理解成“公共广播电台”:系统会通过广播频道发送消息(比如“网络连接改变了”),而你的应用如果订阅了这个频道,就能听到并做出反应。

广播接收器的作用是“监听”这些消息,并在收到时执行相应的逻辑。它不像 Activity 或 Service 那样需要用户主动打开,而是被动等待事件触发。


广播的两种类型:有序与无序

在使用 Android 广播接收器前,必须了解广播的分类。Android 中的广播主要分为两类:

无序广播(Normal Broadcast)

这是最常见的广播类型。所有注册接收该广播的应用都会同时收到消息,彼此之间没有优先级顺序,也无法中断广播流程。比如系统发出“设备重启完成”广播,所有监听此事件的应用都会立刻收到。

有序广播(Ordered Broadcast)

这类广播有明确的执行顺序。系统会按照接收器的优先级(priority)从高到低依次传递广播。高优先级的接收器可以修改广播内容,甚至阻止后续接收器收到广播。

举个生活中的例子:
想象你家小区的广播通知“停电了”。如果是一般广播,所有人同时听到;但如果是有序广播,物业会先通知保安,保安处理完再通知楼长,楼长再通知住户——每一步都可能影响下一步。

在开发中,你需要根据需求选择合适的广播类型。一般情况下,使用无序广播即可满足大多数场景。


创建广播接收器的步骤

创建一个广播接收器分为三个主要步骤:定义接收器类、注册接收器、在 AndroidManifest.xml 中声明。

创建广播接收器类

首先,你需要创建一个类继承自 BroadcastReceiver。这个类将包含你希望在广播到达时执行的逻辑。

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 当广播被触发时,这个方法会被调用
        // 可以在这里写处理逻辑,比如弹出通知、更新 UI 等

        String action = intent.getAction();
        Log.d("MyBroadcastReceiver", "收到广播,动作是:" + action);

        // 比如处理“电池电量低”事件
        if (Intent.ACTION_BATTERY_LOW.equals(action)) {
            Toast.makeText(context, "电池电量过低,请及时充电!", Toast.LENGTH_LONG).show();
        }
    }
}

代码注释说明

  • onReceive() 方法是广播接收器的核心,系统会在收到广播时自动调用。
  • Intent 对象包含了广播的详细信息,如动作(action)、数据、额外参数等。
  • Log.d() 用于调试,打印日志便于追踪广播是否被触发。
  • 通过判断 action 字符串,可以区分不同类型的广播。

注册广播接收器(动态注册)

在代码中动态注册接收器,意味着你可以在运行时决定是否监听某个广播。这种方式更灵活,适合临时监听。

// 在 Activity 或 Service 中注册广播接收器
private MyBroadcastReceiver receiver = new MyBroadcastReceiver();

@Override
protected void onStart() {
    super.onStart();
    
    // 创建 IntentFilter,指定要监听的广播动作
    IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_LOW);
    // 可以添加多个动作
    // filter.addAction(Intent.ACTION_POWER_CONNECTED);
    
    // 注册接收器
    registerReceiver(receiver, filter);
}

@Override
protected void onStop() {
    super.onStop();
    // 一定要在 onStop 时注销,避免内存泄漏
    unregisterReceiver(receiver);
}

重要提醒

  • 动态注册必须在 onStart() 注册,在 onStop() 注销。
  • 如果忘记注销,接收器会一直驻留在内存中,导致内存泄漏。
  • 动态注册的接收器只在应用运行期间有效。

声明在 AndroidManifest.xml(静态注册)

如果你希望应用在未运行时也能接收到广播(比如开机自启、充电通知),就必须使用静态注册。

AndroidManifest.xml 中添加如下代码:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="MyApp"
    android:theme="@style/Theme.AppCompat.Light.DarkActionBar">

    <!-- 静态注册广播接收器 -->
    <receiver android:name=".MyBroadcastReceiver">
        <intent-filter android:priority="100">
            <action android:name="android.intent.action.BATTERY_LOW" />
            <action android:name="android.intent.action.BATTERY_OKAY" />
        </intent-filter>
    </receiver>

    <!-- 其他组件 -->
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

关键点说明

  • android:name 指定接收器类路径。
  • intent-filter 中的 action 定义监听的广播类型。
  • android:priority 设置优先级(数值越大越优先),仅对有序广播有效。
  • 静态注册的接收器即使应用未运行也能被触发。

实际案例:监听网络连接变化

我们来做一个实用的小功能:当用户连接或断开 Wi-Fi 时,自动弹出提示。

步骤一:创建接收器

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();

        if (activeNetwork != null && activeNetwork.isConnected()) {
            // 网络已连接
            Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show();
        } else {
            // 网络断开
            Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show();
        }
    }
}

步骤二:在 AndroidManifest.xml 中注册

<receiver android:name=".NetworkChangeReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

注意

  • android.net.conn.CONNECTIVITY_CHANGE 是系统广播,用于通知网络状态改变。
  • 不需要设置 priority,因为这是无序广播。
  • 该接收器会在网络状态变化时自动触发,无论应用是否在前台运行。

广播接收器的注意事项

在使用 Android 广播接收器时,有几个常见陷阱需要特别注意:

问题 说明 解决方案
内存泄漏 动态注册未注销 onStop()onDestroy() 中调用 unregisterReceiver()
无法收到广播 未正确声明权限或 action 检查 AndroidManifest.xml 中的 action 和权限
安卓 8.0 限制 静态注册的广播被限制 对于后台广播,建议使用 WorkManagerJobScheduler 替代
高耗电风险 接收器频繁触发 尽量只监听必要事件,避免过度使用

尤其需要注意的是,从 Android 8.0(API 26)开始,系统对后台广播进行了严格限制。静态注册的接收器在应用未运行时将无法收到大部分广播(如 ACTION_BATTERY_LOW)。因此,对于需要长期监听的场景,应考虑使用 WorkManagerJobScheduler 等更现代的机制。


总结与建议

Android 广播接收器(Broadcast Receivers)是 Android 系统中不可或缺的通信机制,它让应用能与系统事件“对话”。无论是监听电量、网络、时间变化,还是响应用户操作,广播接收器都扮演着“监听者”的角色。

虽然它的使用看似简单,但实际开发中仍需注意注册与注销的配对、权限声明、以及 Android 8.0 以后的限制。

对于初学者,建议先从动态注册 + 无序广播入手,掌握基本流程后,再尝试静态注册。对于中高级开发者,应了解广播的生命周期、性能影响,并在合适场景下用 WorkManager 等替代方案。

掌握广播接收器,是迈向 Android 系统级开发的重要一步。希望这篇文章能帮你扫清障碍,让每一次广播都能“精准送达”。