Android 四大组件之广播_android 广播-程序员宅基地

技术标签: android  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)) {
    
            // 执行相应的操作
            // ...
        }
    }
}

五、拓展阅读和资源

广播概览

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42886163/article/details/131547431

智能推荐

JVM实战学习——排查java程序 磁盘IO占用过高、CPU占用过高(pidstat)_pidstat查看哪个线程io高-程序员宅基地

文章浏览阅读4.7k次,点赞3次,收藏11次。JVM实战学习——排查java程序 磁盘IO占用过高、CPU占用过高、内存占用过高(pidstat)一、排查cpu高占用1.示例代码使用以下代码,启动的服务会产生cpu资源大量占用的情况1)占有大量CPU资源2)启动类2.查询项目进程1)使用 jps 命令查询项目启动的进程[root]# jps15539 jar ## 其中15539就是项目进程1349 -- process information unavailable15673 Jps2)或者使用 ps -ef |_pidstat查看哪个线程io高

TIOBE 1 月编程语言排行榜:C 语言再度「C 位」出道!_编程语言排行榜tiobe-程序员宅基地

文章浏览阅读1.8w次,点赞88次,收藏103次。整理 | 屠敏出品 | CSDN(ID:CSDNnews)在 2020 年初雪来临之际,TIOBE 官方在最新发布的 1 月编程语言榜单中为我们最终揭开了「 2019 年度编程语言」的神秘面纱,然意料之外情理之中,获此殊荣的并非是风风火火吵闹了一年又一年的 Python,而是一位低调的老兵——C 语言。Python 惜败,C成为 2019 年度编程语言曾几何时,凭借着“人生..._编程语言排行榜tiobe

Rocket MQ(四)Topic,Topic分片和Queue-程序员宅基地

文章浏览阅读1.1w次,点赞11次,收藏59次。Queue是RocketMQ中的另一个重要概念。在对该概念进行分析介绍前,我们先来看一张图:从本质上来说,RocketMQ中的Queue是数据分片的产物。为了更好地理解Queue的定义,我们还需要引入一个新的概念:Topic分片。在分布式数据库和分布式缓存领域,分片概念已经有了清晰的定义。同理,对于RocketMQ,一个Topic可以分布在各个Broker上,我们可以把一个Topic分布在一个Broker上的子集定义为一个Topic分片。对应上图,TopicA有3个Topic分片,分布在Broker

彻底解决Compiling for iOS xxx, but module ‘xxx‘ has a minimum deployment target of iOS xxx 错误_compiling for ios 9.0, but module 'reactiveswift' -程序员宅基地

文章浏览阅读1.1w次。target ios版本和第三方库ios版本问题问题描述解决方法查看iphone iPad target的最低ios版本修改pod里第三方库问题描述这几天编辑xcode偶尔会发现这个错误,但是有时候重新编译一下错误就消失了,今天彻底解决一下这个错误错误提示:Compiling for iOS 10.0, but module ‘SwiftyJSON’ has a minimum deployment target of iOS 12.0: /Users/tdw/Library/Developer/Xc_compiling for ios 9.0, but module 'reactiveswift' has a minimum deployment t

Android NDK thread 回收crash, signal 4 (SIGILL), code 1 (ILL_ILLOPC) , fault addr 地址-程序员宅基地

文章浏览阅读2.8k次。Android NDK thread 回收crash, signal 4 (SIGILL), code 1 (ILL_ILLOPC) , fault addr 地址在NDK c++ 使用pthread_create 创建线程,不管是可分离线程还是非可分离的线程,在回收的时候都有这个问题,ndk-stack 定位到的问题行发现一切正常,卡了好几天,网上查了好久,看到了一篇帖子https://w...

NOI题库答案 (1.7 字符串基础)(1-20)-程序员宅基地

文章浏览阅读1.9w次,点赞20次,收藏64次。 01:统计数字字符个数描述输入一行字符,统计出其中数字字符的个数。输入一行字符串,总长度不超过255。输出输出为1行,输出字符串里面数字字符的个数。样例输入Peking University is set up at 1898.样例输出4#include&lt;bits/stdc++.h&gt;using namespace std;in...

随便推点

编译与链接的问题 gcc -fPIC -shared_symbol `g_hall_mode' can not be used when making a-程序员宅基地

文章浏览阅读2.8k次。地址无关代码,在64位下编译动态库的时候,经常会遇到下面的错误/usr/bin/ld: /tmp/ccQ1dkqh.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC提示说需要-fPIC编译,然后在链接_symbol `g_hall_mode' can not be used when making a shared object; recompile

SpringCloud之高可用的分布式配置中心(Spring Cloud Config)(七)-程序员宅基地

文章浏览阅读39次。当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如下:准备工作继续使用上一篇文章的工程,创建一个eureka-server工程,用作服务注册中心。在其pom.xml文件引入Eureka的起步依赖spring-cloud-starter-netflix- eureka-server,代码如下:<?xml version=...

c语言中.和->区别,c语言中"->"和"."的区别-程序员宅基地

文章浏览阅读3.5k次,点赞7次,收藏21次。对于c语言中"->"和"."的区别总结如下:1、A.B则A为对象或者结构体;2、A->B则A为指针,->是成员提取,A->B是提取A中的成员B,A只能是指向类、结构、联合的指针;3、(*a).b 等价于 a->b。"."一般情况下读作"的”; “->”一般读作"指向的结构体的"。也就是说在结构中,运算符->是运算符*和运算符.的结合4、“->”是指向..._->和.

ubuntu20.04安装ROS2 详细教程-程序员宅基地

文章浏览阅读2.1w次,点赞27次,收藏218次。ubuntu20.04安装ROS2_ubuntu20.04安装ros2

人工智能之华为云5G基站有AI,智能处理流量“潮汐”-程序员宅基地

文章浏览阅读1.9k次,点赞3次,收藏16次。一、5G 基站能否智能“省电”?① 能耗和能效随着中国 5G 基站部署规模的扩大,5G 基站能耗惊人的说法甚嚣尘上,众口铄金,5G 基站似乎坐实“电老虎”的尴尬地位。如下是一张某运营商的内部流出照片,从中可以看出,5G AAU 和 4G RRU 的满载功耗相差极为悬殊,不得不承认 5G 的能耗确实远高于 4G:在移动的节能技术白皮书中,也明确地写着:“2019 年初 5G 基站功耗约为 4G 基站的 3~4 倍,高功耗是运营商大规模部署 5G 的棘手问题”:联通也在其白皮书中写道:“5

flyme8.1.5.0A精简内置软件包_flyme8精简-程序员宅基地

文章浏览阅读6k次。flyme8.1.5.0A系统精简内置软件包提示:精简系统有风险 在精简之前先备份资料 sdcard目录放置官网刷机包以备重新刷机在pc端用adb命令精简手机系统手机端打开usb调试模式 设置 ———关于手机————版本号 点击6~8次进入开发者模式设置————辅助功能————开发者选项————开启开发者选项 打开usb调试platform-tools下载地址https://developer.android.com/studio/releases/platfor_flyme8精简