Android 四大组件之广播

一、导言

在Android应用开发中,广播组件是一项关键技术,被广泛用于各种任务和场景。无论是发送系统级广播,还是在应用内部实现组件间的通信,了解和掌握广播组件的工作原理和使用方法对于每个Android开发者来说都是至关重要的。本文旨在帮助你深入了解Android广播组件,并给出一些实用的技巧和建议。

带着问题去学习

什么是广播?
广播包含哪些功能?
广播是如何发送和接收的?
如何注册广播,都有哪些注册方式?
都有哪些系统广播?
静态注册和动态注册有什么区别?
Android 如何快速创建一个广播接收器?
如何发送自定义广播?
广播都有哪些类型?
使用广播需要注意哪些安全合规问题?

二、什么是广播(what)

广播(Broadcast)是Android操作系统中一种用于应用程序之间或应用程序内部进行通信的机制。它允许一个应用程序发送消息(广播事件),而其他应用程序可以接收并对这些消息做出响应。

三、广播的发送

1、系统广播

系统广播是由Android操作系统自身发出的广播,用于通知应用程序有关设备状态和系统事件的变化。

常见的系统广播

广播动作 描述 说明
android.net.conn.CONNECTIVITY_CHANGE 网络状态变化 当设备的网络连接状态发生变化时发送的广播。可以通过监听该广播来检测网络连接的变化,并相应地调整应用程序的行为。
android.intent.action.BATTERY_CHANGED 设备电量变化 当设备的电池电量发生变化时发送的广播。应用程序可以通过监听该广播来获取当前电池电量的信息,并根据电量的变化做出相应的操作。
android.intent.action.SCREEN_ON 屏幕开启 当设备的屏幕被开启时发送的广播。应用程序可以通过监听该广播来执行特定的操作,如启动屏幕相关的功能。
android.intent.action.SCREEN_OFF 屏幕关闭 当设备的屏幕被关闭时发送的广播。应用程序可以通过监听该广播来执行相应的操作,如关闭屏幕相关的功能。
android.intent.action.BOOT_COMPLETED 设备启动完成 当设备启动完成后发送的广播。应用程序可以通过监听该广播来执行一些初始化操作或启动特定的服务,以确保应用程序在设备启动后正常运行。
android.intent.action.TIMEZONE_CHANGED 时区变化 当设备的时区发生变化时发送的广播。应用程序可以根据时区的变化来调整与时间相关的功能。
android.intent.action.AIRPLANE_MODE 飞行模式变化 当设备的飞行模式开启或关闭时发送的广播。应用程序可以通过监听该广播来做出相应的操作。
android.intent.action.MEDIA_MOUNTED 存储媒体已挂载 当存储媒体(如SD卡)被挂载到设备上时发送的广播。应用程序可以通过监听该广播来响应存储媒体的挂载事件。
android.intent.action.MEDIA_REMOVED 存储媒体已移除 当存储媒体(如SD卡)从设备中移除时发送的广播。应用程序可以通过监听该广播来做出相应的处理。
android.intent.action.PACKAGE_ADDED 应用程序安装完成 当应用程序安装完成后发送的广播。应用程序可以通过监听该广播来执行相应的操作。
android.intent.action.PACKAGE_REMOVED 应用程序卸载完成 当应用程序卸载完成后发送的广播。应用程序可以通过监听该广播来执行相应的操作。
android.intent.action.HEADSET_PLUG 耳机插拔事件 当耳机被插入或拔出设备时发送的广播。应用程序可以通过监听该广播来做出相应的处理。
android.intent.action.WALLPAPER_CHANGED 壁纸变化 当设备的壁纸发生变化时发送的广播。应用程序可以通过监听该广播来做出相应的处理。

2、自定义广播

在Android中,自定义广播的发送类型与系统广播类似,可以使用标准广播、有序广播和粘性广播

1. 标准广播(Normal Broadcast)

标准广播(Normal Broadcast)是Android中一种常见的广播类型。它是一种异步广播,意味着发送广播后,发送者不会等待接收者的处理结果,而是立即返回。所有匹配该广播的接收者都会同时接收到广播消息。

特点
  1. 广播的发送者不会知道有哪些接收者接收到了广播消息,也无法影响接收者的执行顺序。
  2. 接收者无法中断或取消广播的传递。
  3. 广播的发送和接收是完全异步的,发送者和接收者之间没有直接的交互。
标准广播适用的情况
  • 广播消息不需要有序处理,即接收者之间的执行顺序不重要。
  • 广播消息的发送者不关心接收者的处理结果。
  • 需要将广播发送给所有匹配的接收者,而不需要对广播进行特定的筛选。
代码实现示例
// 创建Intent对象
Intent intent = new Intent();

// 设置广播的动作
intent.setAction("com.example.MY_CUSTOM_ACTION");

// 发送有序广播
sendBroadcast(intent, null);

2. 有序广播(Ordered Broadcast)

有序广播(Ordered Broadcast)是Android中另一种常见的广播类型。与标准广播不同,有序广播是按照优先级顺序依次发送给匹配的接收者,并且每个接收者在处理广播后可以选择终止广播或将广播传递给下一个接收者。

特点
  • 有序广播允许接收者按照优先级顺序处理广播消息。接收者可以通过设置优先级来控制自己在广播链中的执行顺序。
  • 每个接收者可以中断广播的传递,以防止其他接收者继续接收广播消息。
  • 有序广播的发送者可以获取接收者处理广播的结果,因为每个接收者可以返回一个结果代码。
有序广播适用的情况
  • 需要按照特定的顺序处理广播消息,确保接收者按照预期的顺序执行。
  • 需要控制广播的传递,允许接收者中断广播的传递。
  • 需要接收者之间进行通信和协作,通过设置结果代码来返回结果给广播发送者。
代码实现示例
// 创建Intent对象
Intent intent = new Intent();

// 设置广播的动作
intent.setAction("com.example.MY_CUSTOM_ACTION");

// 发送有序广播
sendOrderedBroadcast(intent, null);

3. 粘性广播(Sticky Broadcast)

粘性广播(Sticky Broadcast)是Android中一种特殊类型的广播。与标准广播和有序广播不同,粘性广播会保留在系统中,即使没有匹配的接收者。当有新的接收者注册时,它们会立即收到最新的粘性广播。

特点
  • 粘性广播会被保留在系统中,直到有新的接收者注册为止。即使广播已经发送过一段时间,接收者仍然可以接收到最新的广播消息。
  • 接收者注册后会立即收到最新的粘性广播消息,无需等待下一次广播发送。
  • 粘性广播可以用于将应用程序的状态信息传递给未运行的组件,或者在应用程序重新启动后恢复之前的状态。
粘性广播适用的情况
  • 需要在接收者注册之前发送广播,以确保接收者能够立即获取到最新的广播消息。
  • 需要将广播消息传递给未运行的组件,以便它们能够在接收到广播后立即处理。
  • 需要在应用程序重新启动后恢复之前的状态,通过接收之前发送的粘性广播消息。
代码实现示例
// 创建Intent对象
Intent intent = new Intent();

// 设置广播的动作
intent.setAction("com.example.MY_CUSTOM_ACTION");

// 发送粘性广播
sendStickyBroadcast(intent);

3、本地广播

本地广播(Local Broadcast)是一种特定于应用程序内部的广播机制,用于在应用程序的内部组件之间进行通信。与全局广播不同,本地广播只在应用程序的边界内传播,不会离开应用程序的上下文。

特点

  • 本地广播只在应用程序内部传播,不会泄露给其他应用程序,提供了更高的安全性。
  • 本地广播的传播范围被限制在应用程序的边界内,不会对其他应用程序产生影响。
  • 本地广播的发送和接收是同步的,即发送者会等待接收者的处理结果。

本地广播适用的情况

  • 在应用程序内的组件之间进行通信,而不希望将广播传递给其他应用程序。
  • 需要确保广播消息仅在应用程序的内部有效,避免对其他应用程序产生意外影响。
  • 需要同步等待接收者处理广播消息的结果。

代码示例

// 创建Intent对象
Intent intent = new Intent();

// 设置广播的动作
intent.setAction("com.example.MY_LOCAL_ACTION");

// 发送本地广播
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

四、广播的接收

在Android中,要接收广播,需要创建一个广播接收器(BroadcastReceiver)。广播接收器是一个组件,用于接收和处理发送到应用程序的广播消息。

1. 创建广播接收器类

创建一个继承自BroadcastReceiver的类,并实现onReceive(Context, Intent)方法。在onReceive方法中编写接收到广播后的处理逻辑。

public class MyBroadcastReceiver extends BroadcastReceiver {
    
    
    @Override
    public void onReceive(Context context, Intent intent) {
    
    
        // 在这里编写接收到广播后的处理逻辑
        // 根据广播的动作或其他信息进行相应的操作
    }
}

2. 注册广播接收器

1. 静态注册(Static Registration)

  • 静态注册是在应用程序的清单文件(AndroidManifest.xml)中进行注册,通过在标签中声明广播接收器的类名和相关配置。
  • 静态注册的广播接收器会在应用程序安装时被系统知晓,无论应用程序是否运行,都可以接收广播消息。
  • 示例:
<receiver
    android:name=".MyBroadcastReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.MY_CUSTOM_ACTION" />
    </intent-filter>
</receiver>

2. 动态注册(Dynamic Registration)

  • 动态注册是在应用程序的代码中使用registerReceiver()方法动态注册广播接收器。
  • 动态注册的广播接收器只在调用registerReceiver()方法后才能接收到广播消息,并且在适当的时候需要调用unregisterReceiver()方法取消注册,以避免内存泄漏。
  • 示例:
// 创建广播接收器实例
MyBroadcastReceiver receiver = new MyBroadcastReceiver();

// 创建IntentFilter对象,并添加接收的广播动作
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.MY_CUSTOM_ACTION");

// 注册广播接收器
context.registerReceiver(receiver, filter);

3. 处理接收到的广播

接收到广播后,需要在广播接收器(BroadcastReceiver)的onReceive(Context, Intent)方法中编写处理逻辑

1. 在广播接收器类中实现onReceive方法

public class MyBroadcastReceiver extends BroadcastReceiver {
    
    
    @Override
    public void onReceive(Context context, Intent intent) {
    
    
        // 在这里编写接收到广播后的处理逻辑
    }
}

2. 通过Intent对象获取广播的相关信息

  • 动作(Action):使用getAction()方法获取广播的动作,可以根据动作类型执行相应的操作。
  • 数据(Data):使用getData()方法获取广播的数据,如果广播携带了数据的话。
  • 额外信息(Extras):使用getExtras()方法获取广播的额外信息,可以通过键值对的形式获取特定的信息。
  • 示例:
public class MyBroadcastReceiver extends BroadcastReceiver {
    
    
    @Override
    public void onReceive(Context context, Intent intent) {
    
    
        String action = intent.getAction();
        Uri data = intent.getData();
        Bundle extras = intent.getExtras();
        
        // 根据广播的动作、数据或额外信息进行相应的处理
    }
}

3. 执行相应的操作

  • 根据广播的动作或其他信息,执行适当的操作,例如更新UI、启动服务、发送通知等。
  • 可以使用上下文(Context)对象来执行特定的操作,例如启动Activity、获取系统服务等。
  • 示例
public class MyBroadcastReceiver extends BroadcastReceiver {
    
    
    @Override
    public void onReceive(Context context, Intent intent) {
    
    
        String action = intent.getAction();
        
        if ("com.example.MY_CUSTOM_ACTION".equals(action)) {
    
    
            // 执行相应的操作
            // ...
        }
    }
}

五、拓展阅读和资源

广播概览

猜你喜欢

转载自blog.csdn.net/qq_42886163/article/details/131547431
今日推荐