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,一经查实,立即删除!

相关文章

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;使成型加工更为完善&…

机器学习鸢尾花使用csv

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

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

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组件名 跳转…

Golang图像处理实战:image/png包的应用详解

Golang图像处理实战&#xff1a;image/png包的应用详解 介绍基本操作读取PNG文件保存PNG文件 处理图像数据修改图像像素图像裁剪和缩放 高级功能使用 image/color 处理颜色优化PNG性能 错误处理与调试常见错误及其解决方法文件无法打开图像解码失败 使用工具和库进行调试 结语 …

测试数据整理--chatgpt 构造sql语句导出数据库数据

在测试过程中&#xff0c;我们有时候需要准备一些测试数据&#xff0c;若从系统中直接导出Excel数据&#xff0c;数据往往庞大且需要整合&#xff0c;不好整理&#xff0c;于是我们直接去数据库中查询一些表&#xff0c;数据整合后直接导出结果会更方便。 我们今天就 用 chatg…

shell 调用钉钉通知

使用场景&#xff1a;机器能访问互联网&#xff0c;运行时间任务后通知使用 钉钉建立单人群 手机操作&#xff0c;只能通过手机方式建立单人群 电脑端 2. 配置脚本 #!/bin/bash set -e## 上图中 access_token字段 TOKEN KEYWORDhello # 前文中设置的关键字 function call_…

【jinja2】模板渲染

HTML文件 return render_template(index.html)h1: 一级标题 变粗变大&#xff08;狗头

B02、JVM调优案例

1、调优的基本问题 1.1、为什么要调优&#xff1f; 目的是防止出现OOM&#xff0c;进行JVM规划和预调优&#xff1b;解决程序运行中各种OOM&#xff1b;以及减少Full GC出现的频率&#xff0c;解决运行慢、卡顿问题。 1.2、调优的大方向 合理的编写代码&#xff0c;充分并合理…

大气的免费wordpress模板

国产的wordpress模板&#xff0c;更适合中国人使用习惯&#xff0c;更符合中国老板的审美的大气wordpress企业官网建站模板。 WordPress模板&#xff0c;也称为主题&#xff0c;是用于定义WordPress网站或博客外观和功能的预设计文件集。这些模板使用HTML、CSS和PHP代码构建&a…

鸢尾花数据集的KNN探索与乳腺癌决策树洞察

鸢尾花数据集的KNN探索与乳腺癌决策树洞察 今天博主做了这个KNN和决策树的实验。 一.数据集介绍 介绍一下数据集&#xff1a; 威斯康星州乳腺癌数据集&#xff1a; 威斯康星州乳腺癌数据集&#xff08;Wisconsin Breast Cancer Dataset&#xff09;是一个经典的机器学习数…

【简单介绍下Beego框架】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

探索 Nacos反序列化漏洞CNVD-2023-45001

在软件开发领域&#xff0c;安全漏洞是一项不容忽视的重要问题。最近&#xff0c;我们的安全团队发现了一个影响到我们的Nacos 2.1.0版本的反序列化漏洞&#xff0c;可能带来严重的安全威胁。我们已经立即采取了修复措施。本文将深入探讨这些漏洞的原理、可能造成的影响&#x…