Android Studio学习笔记——广播机制Broadcast

Android Studio学习笔记——广播机制

  • 5.1 广播机制简介
  • 5.2 接收系统广播
    • 5.2.1 动态注册监听网络变化
    • 5.2.2 静态注册实现开机启动
  • 5.3 发送自定义广播
    • 5.3.1 发送标准广播
    • 5.3.2 发送有序广播
  • 5.4 使用本地广播
  • 5.5 广播的最佳实践——强制下线功能

5.1 广播机制简介

安卓每个应用程序都可以对自己感兴趣的广播进行注册,要该程序就只会接收到自己所关心的广播内容。这些广播可能是来自于系统的,也可能是来自于其他应用。安卓提供了一套完整的API,允许应用程序自由的发送和接收广播。安卓中的广播主要可以分为两种类型:标准广播和有序广播。
标准广播Normal broadcasts是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播信息。他们之间没有任何先后顺序。这种广播效率会比较高。但同时也意味着他是无法被截断的。
有序广播 ordered Broadcasst是一种同步执行广播。在广播发出之后,同意时刻只会有一个广播接收器能够接收到这条广播。当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时广播接收器是有先后顺序的。优先级高的广播接收器,就可以先接收到广播信息。并且前面的广播接收器还可以截断正在传递的广播。这样后面的广播接收器就无法收到广播信息。

5.2 接收系统广播

注册广播的方式有两种。在代码中注册称为动态注册,在AndroidManifest.xml中注册成为静态注册。

5.2.1 动态注册监听网络变化

在代码中注册广播(动态注册),动态注册的广播接收器一定都要取消注册才行,通过onDestroy方法中调用unregister方法来实现。

public class MainActivity extends AppCompatActivity {private IntentFilter intentFilter;private NetworkChangeReceiver networkChangeReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});intentFilter = new IntentFilter();intentFilter.addAction("android.net.com.CONNECTIVITY_CHANGE");networkChangeReceiver = new NetworkChangeReceiver();registerReceiver(networkChangeReceiver,intentFilter);}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(networkChangeReceiver);}
}
public class NetworkChangeReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();}
}

5.2.2 静态注册实现开机启动

动态注册的广播可以自由的控制注册与注销,在灵活性方面有很大的优势,但是它也存在着一个缺点,即必须在程序启动之后才能接收到广播,因为注册的逻辑是写在OnCreate方法中的。
如果想要在程序未启动的时候就能接受到广播,需要使用静态注册的方法。
创建new->Other->BroadcastReceiver,弹出创建Broadcast的窗口。创建一个BootCompleteReceiver的广播接收器。

public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO: This method is called when the BroadcastReceiver is receiving// an Intent broadcast.Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();throw new UnsupportedOperationException("Not yet implemented");}
}

静态广播注册接收器一定要在AndroidManifest.xml文件中注册才能使用。上一步创建广播接收器,在在AndroidManifest.xml中的注册会自动完成。

<receiverandroid:name=".BootCompleteReceiver"android:enabled="true"android:exported="true"></receiver>

在<//applicaton>标签内多了一个新的标签《receiver》,所有的静态广播注册都是在这里注册的。通过android:name来具体指定注册哪一个广播接收器。
目前BootCompleteReceiver还是不能接收到开机广播,还需要对AndroidManifest.xml文件进行修改才行。
在这里插入图片描述
因为Android系统启动后会发出一条android.intent.action.BOOT_COMPLETED的广播,所以在接收器的《intent-filter》中添加相应action。
注意:
不要在OnReceive方法中添加过多的逻辑或其他耗时的操作,因为在广播接收器中是不允许开启线程的,当OnReceive方法运行了较长时间而没有结束,程序就会报错。因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。

5.3 发送自定义广播

5.3.1 发送标准广播

public class MainActivity extends AppCompatActivity {...@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});Button button=(Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent= new Intent("com.example.broadcast.MY_BROADCAST");sendBroadcast(intent);}});}}

广播是一种跨进程通信的方式。
验证该方式,可以新建一个BroadcastTest2项目,点击File-》new-》New Project进行创建。
将项目创建好之后,还需要在这个项目下定义一个广播接收器,用于接收上面的自定义广播。
在这里插入图片描述
在BroadcastTest2项目中AnotherBroadcastReceiver同样是接收com.example.broadcasttest.MY_BROADCAST这条广播,和BroadcastTest项目中的MyBroadcastReceiver是一样的。
现在运行BroadcastTest2,按home键再去BroadcastTest界面点击button按钮(发送广播),会分别弹出两次提示消息,说明BroadcastTest发送的广播不仅自己接收到,BroadcastTest2也接收到了。

5.3.2 发送有序广播

5.3.1都是标准广播,如果要发送有序广播,重新回到BroadcastTest项目,修改MainActivity中的代码:

public class MainActivity extends AppCompatActivity {...@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});Button button=(Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent= new Intent("com.example.broadcast.MY_BROADCAST");sendOrderedBroadcast(intent,null);}});}}

发送有序广播只需要改动一行代码,这时候广播接受器是有先有顺序的,而且前面的广播接收器还可以将广播截断,以阻止其继续传播。
在注册广播的时候定义广播接收器的先后顺序,修改AndroidManifest.xml中的代码

 <receiverandroid:name=".AnotherBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter android:priority="100"><action android:name="com.example.broadcasttest.MY_BROADCAST" /></intent-filter></receiver>

将MyBroadcastReceiver的优先级设成了100,以保证它一定会在AnotherBroadcastReceiver之前收到广播。
MyBroadcastReceiver有优先权,就可以选择是否允许广播继续传递。

public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO: This method is called when the BroadcastReceiver is receiving// an Intent broadcast.abortBroadcast();//throw new UnsupportedOperationException("Not yet implemented");}
}

abortBroadcast()可以截断广播,终止广播的传递。

5.4 使用本地广播

前面发送和接收的广播全部属于全局广播,即发出的广播可以被其他任何其他应用程序收到,可以接受到来自于其他应用程序的广播。这样很容易引起安全性的问题。如发送一些关键性数据的广播,可能被其他应用去截获,或者其他应用程序不停的向我们的广播接收器发各种垃圾广播。
为了解决广播的安全性问题,安卓引入了一套本地广播机制。使用这个广播只能够在应用程序的内部进行传播。并且广播接收器也只能接受来自本应用程序发出的广播。
本地广播的用法并不复杂,主要就是用了一个LocalBroadcastManager来对广播进行管理。并提供了发送广播和注册广播接收器的方法。

public class MainActivity extends AppCompatActivity {private IntentFilter intentFilter;//private NetworkChangeReceiver networkChangeReceiver;private LocalReceiver localReceiver;private LocalBroadcastManager localBroadcastManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});//intentFilter = new IntentFilter();//intentFilter.addAction("android.net.com.CONNECTIVITY_CHANGE");//networkChangeReceiver = new NetworkChangeReceiver();//registerReceiver(networkChangeReceiver,intentFilter);localBroadcastManager=LocalBroadcastManager.getInstance(this);Button button=(Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//Intent intent= new Intent("com.example.broadcast.MY_BROADCAST");//sendBroadcast(intent);//sendOrderedBroadcast(intent,null);Intent intent= new Intent("com.example.broadcast.LOCAL_BROADCAST");localBroadcastManager.sendBroadcast(intent);}});intentFilter = new IntentFilter();intentFilter.addAction("android.net.com.LOCAL_CHANGE");localReceiver= new LocalReceiver();localBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册本地广播监听器}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(networkChangeReceiver);}
}
public class LocalReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context,"received local broadcast",Toast.LENGTH_SHORT).show();}
}

本地广播是无法通过静态注册的方式来接收的。

5.5 广播的最佳实践——强制下线功能

后续更新git链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/826005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web server apache tomcat11-08-JNDI Resources

前言 整理这个官方翻译的系列&#xff0c;原因是网上大部分的 tomcat 版本比较旧&#xff0c;此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎&#xff0c;轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…

spring boot后端开发基础

spring boot后端开发基础 Spring Boot一、开发步骤二、Web分析三、跨域问题四、HTTP协议五、Web服务器六、响应前端请求七、springboot常用注解创建一个简单的RESTful API服务层和数据访问层配置类和Bean定义响应体和路径变量 Spring Boot 一、开发步骤 创建项目 添加依赖 项…

k8s部署Eureka集群

部署有状态负载 镜像配置&#xff1a; 环境变量如下&#xff1a; AUTHENTICATE_ENABLEtrue JAVA_OPTS-Dauth.userName账号 -Dauth.password密码 MY_POD_NAMEmetadata.name BOOL_REGISTERtrue BOOL_FETCHtrue APPLICATION_NAME负载名称 EUREKA_INSTANCE_HOSTNAME${MY_POD_NA…

webpack源码分析——enhanced-resolve库之getType、normalize、join和cachedJoin函数

一、PathType 路径类型 const PathType Object.freeze({Empty: 0, // 空Normal: 1, // 默认值Relative: 2, // 相对路径AbsoluteWin: 3, // win 下的绝对路径AbsolutePosix: 4, // posix 下的绝对路径Internal: 5 // enhanced-resolve 内部自定义的一种类型&#xff0c;具体是…

小程序AI智能名片S2B2C商城系统:做内容、造IP、玩社群打造私域流量的新营销秘籍

在数字化浪潮汹涌的新时代&#xff0c;小程序AI智能名片S2B2C商城系统正以其独特的魅力&#xff0c;引领着营销领域的新变革。这套系统不仅将人工智能与小程序技术完美结合&#xff0c;更通过创新的S2B2C模式&#xff0c;为企业打开了一扇通往成功的大门。 面对激烈的市场竞争&…

SQL注入作业

目录 一、万能密码和二阶注入测试 1.万能密码 2.二阶注入测试 二、联合查询注入测试 1.判断注入点 2.判断当前查询语句的列数 3.查询数据库基本信息 4.查询数据库中的数据 三、报错注入 1. 报错注入函数EXTRATVALUE 2.UPDATEXML 四、盲注测试 1.布尔盲注 判断数据…

Linux搭建Discuz论坛

搭建一个论坛 —接上篇博客 改名/etc/httpd/conf.d/vhosts.conf 》/etc/httpd/conf.d/vhosts.conf.bak [rootlocalhost conf.d]# mv /etc/httpd/conf.d/vhosts.conf /etc/httpd/conf.d/vhosts.conf.bak此时的vhosts.conf是一个新创建的文件&#xff0c;之前的vhosts.conf已经…

使用 Godot 游戏引擎为 Apple 的 visionOS 创建游戏和应用的平台

借助GodotVision ,您可以使用Godot 游戏引擎为 Apple VisionOS创建游戏和应用程序。 保卫牛城堡,一款使用 GodotVision 制作的 VisionOS 游戏 GodotVision 运行一个控制本机RealityKit 视图的无头 Godot实例。粗略地说:Godot 是后端,

毅速3D打印随形透气钢:革新传统,引领未来

透气钢&#xff0c;这种多孔金属材料&#xff0c;既融合了金属材料的坚固性&#xff0c;又具备了透气材料的通透性。尤其在注塑模具的制造中&#xff0c;透气钢的作用不可忽视。通过镶嵌透气钢&#xff0c;能够有效解决因困气产生的注塑问题&#xff0c;使成型加工更为完善&…

【机器学习】机器学习学习笔记 - 监督学习 - 逻辑回归分类朴素贝叶斯分类支持向量机 SVM (可分类、可回归) - 04

逻辑回归分类 import numpy as np from sklearn import linear_modelX np.array([[4, 7], [3.5, 8], [3.1, 6.2], [0.5, 1], [1, 2], [1.2, 1.9], [6, 2], [5.7, 1.5], [5.4, 2.2]]) y np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])# 逻辑回归分类器 # solver&#xff1a;求解器&a…

C字符串操作strlenstrnlen_s详解

前言 strcat、strcpy、strcmp、strlen是C中针对字符串的库函数&#xff0c;这四个函数不安全&#xff0c;然后C针对这个情况整出strcat_s、strcpy_s、strncmp、strnlen_s(这个并不是替代stelen的)来弥补。 这篇文章主要讲&#xff1a;strlen以及strnlen_s的用法。 详见C字符串…

SpringBoot项目整合Knife4j接口文档

文章目录 什么是接口文档&#xff1f;谁用接口文档为什么需要接口文档怎么做接口文档springboot如何整合knife4j?1.引入依赖2.在config目录下创建Knife4j配置依赖3.在appliacation.yml中进行配置4.启动Spring Boot工程&#xff0c;在浏览器中访问&#xff1a;http://localhost…

文件传输服务器是否支持文件的增量备份?

文件传输服务器通常并不直接支持增量备份&#xff0c;因为文件传输服务器的主要功能是提供文件传输服务&#xff0c;而不是备份服务。然而&#xff0c;你可以在文件传输服务器上实现增量备份的功能&#xff0c;方法如下&#xff1a; 使用备份软件&#xff1a;安装并配置专门的备…

机器学习鸢尾花使用csv

操作流程 下载鸢尾花数据集导入需要的包读取数据并查看数据大小和长度划分训练集和测试集使用模型评估算法 下载鸢尾花数据集 链接&#xff1a;https://pan.baidu.com/s/1RzZyXsaiJB3e611itF466Q?pwdj484 提取码&#xff1a;j484 --来自百度网盘超级会员V1的分享导入需要…

【力扣 | 分享】高频 SQL 50 题(基础版)

题单 查询可回收且低脂的产品寻找用户推荐人大的国家文章浏览 I无效的推文 连接使用唯一标识码替换员工ID产品销售分析 I进店却未进行过交易的顾客上升的温度每台机器的进程平均运行时间员工奖金学生们参加各科测试的次数至少有5名直接下属的经理确认率有趣的电影平均售价项目员…

ZCC51215同步降压芯片 输出电流30A

描述&#xff1a; ZCC51215是一颗用于 Notebook 或Desktop的同步降压 控制器。具有 4V 到 24V 的宽输入电压范围&#xff0c;适用于锂 电池或者适配器供电。输出电压可以通过 VID0和 VID1 逻辑信号动态切换&#xff0c;电压切换斜率可以通过 VREF 引脚 的电容进行配置&…

react异步组件如何定义使用 标准使用方法

目录 默认导出和命名导出的格式 默认导出的组件 使用方式 命名导出的组件 使用方式 默认导出和命名导出的格式 默认导出: // person.js const person {name: Alice,age: 30 };export default person;命名导出&#xff1a; // math.js export const add (a, b) > a b; exp…

矩阵混乱度(熵值)代码计算

1、先回顾下熵值的数据公式&#xff1a; 2、jax.numpy代码 注意的点&#xff1a;熵值计算的输入的必须是归一化的正值 import jax.numpy as jnp import jax def _entroy(probs):log_probs jnp.log2(jnp.maximum(1.0e-30, probs))mean_sum_plogp jnp.mean(- jnp.sum(log_pro…

vscode+vue开发常用插件整理

前言&#xff1a; vscode新机开发常用插件整理 1、chinese 简体中文配置 2、file-jump 别名跳转&#xff0c;可以把引入的组件&#xff0c;通过ctrl地址名 跳转组件内部 3、Vue Peek&#xff1a;vue项目中的一些配置&#xff0c;安装后&#xff0c;能实现 ctrl组件名 跳转…

python中用struct打包

Python字节流打包是指将数据按照一定的格式打包成字节流的过程。在Python中&#xff0c;可以使用struct模块来进行字节流的打包和解包操作。 struct模块提供了一些函数&#xff0c;用于将数据转换为特定的字节流格式&#xff0c;或者将字节流解析为特定的数据类型。常用的函数…