当前位置: 首页 > news >正文

Android-广播详解

目录

动态注册

静态注册:

显示广播和隐式广播的区别:

标准广播和有序广播的发送:

发送有序广播

发送无序广播

使用本地广播:


广播的分类:

按照发送方式分类:

  1. 标准广播

是一个完全异步执行的广播,几乎同时的接收器会收到这个广播,效率比较高,无法截断;

     2. 有序广播

是同步执行,同一时刻只有一个接受器才能接受到消息,优先级高的接收器先接受到,同时也可以进行截断

     3. 本地广播

应用内广播,不会被其他应用接收到,更安全,不会泄露信息,但只能用于同一个 app 内部通信。

      4. 粘性广播

广播发送后会一直保留,即使接收器之后才注册也能收到最近的一条广播,但可能造成数据泄露、资源占用;

但如果按照注册方式分类,可以分为静态注册和动态注册:我们先来看看动态注册:

动态注册

我们来对过程做一个解析:

  1. 自定义一个网络接收器的类:继承BroadcastReceiver;

  2. 注册:new一个intentfilter对象,通过对象的addAction方法,可以将我们所要接受的广播进行添加;最后获得网络接收器的实例,通过方法registerReceiver(),有两个参数,第一个参数是网络接收器的对象,第二个参数是intentfilter的对象;

  3. 因为是动态在Oncreat里面注册的对象,所以还需要在onDestory的时候进行销毁:调用unregisterReceiver(网络接收器的对象);

  4. 我们还需要判断是否有网络进行具体的提示:

通过方法getSystemService方法得到服务类ConnectiVITYManager的实例,参数是Context.CONNECTIVITY_SERVICE,然后通过实例的getActiveNetWorkInfo()方法,得到networkinfo的对象,通过isAvailable方法的判断;

上面这段是判断有无网络的提示,如果您只是单纯想学习广播的话,可以不用看,但最好完成这个案例;代码如下:


public class MainActivity extends AppCompatActivity {private  NetworkChangeReceiver ncr;@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 intentfilter = new IntentFilter();intentfilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");ncr  = new NetworkChangeReceiver();registerReceiver(ncr,intentfilter);}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(ncr);}class NetworkChangeReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();if(activeNetworkInfo!=null && activeNetworkInfo.isAvailable()){Toast.makeText(context,"uesablae",Toast.LENGTH_SHORT).show();}else{Toast.makeText(context,"unuseable",Toast.LENGTH_SHORT).show();}}}

为了大家理解,我把重点的代码贴到这里:
 

    IntentFilter intentfilter = new IntentFilter();intentfilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");ncr  = new NetworkChangeReceiver();registerReceiver(ncr,intentfilter);

静态注册:

不是所有的都允许静态注册,要根据最新的文档来确定:

要点如下:

  1. 不用打开app,也能实现注册;

  2. 步骤是:在包下创建一个接收器,在接收器的onrecive方法中,弹出提示消息,作为我们的成果演示;

  3. 添加intentfilter标签,同时也需要得到许可:user-permisssion

<receiverandroid:name=".BootCompleteReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter>
</receiver>
//许可
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

以上都是在androidmanifest,xml文件中进行的;

pay attention to!!!

不建议添加过多的逻辑,因为不允许开启线程,当有onreceive方法耗时操作时,程序就会报错 ;

显示广播和隐式广播的区别:

显示广播:指明确了我要发的组件,通过intent.setpackage()参数是getPackageName();

通过方法指定了广播目标所属的包名,只会发给app中具有对应action的接收器

隐式广播: 不指定接收器,只指定action,所有注册action的接收器选择谁来接收

Android8.0以后静态注册只接受显示广播,除了系统广播;

那么有人要问了,我在这里为什么要强调显示广播和隐式广播的区别呢?

是因为:

  • 从 Android 8.0 开始,系统对静态注册的隐式广播进行了限制,以减少后台资源消耗、提升性能;

  • 被系统限制的隐式广播只支持显式广播的方式发送;

标准广播和有序广播的发送:

发送有序广播

1. 通过Intent对象,参数是广播的值,跟注册接受广播器的action是一致的,都包括包名.名字;

  1. 通过方法:sendBoradcast(intent对象)来发送信息;

发送无序广播

  1. 可以通过在XML文件中的广播组件中,利用android:priority来设置优先级;

  2. 通过sendOrderedbroadcase(intent,null)来发送

因为两者代码只有一处不一样,所以这里就贴出一段代码: 

Intent a = new Intent("com.example.broadcasttest.MY_M ES");
a.setPackage(getPackageName());
sendOrderedBroadcast(a,null);

使用本地广播:

只需要在类中定义成员变量: 通过LocalBroadcastManager对广播进行管理,并提供了注册和发送广播的方法;

  1. 获取实例:LocalBroadcastManager.getINstance(this)方法

  2. 通过实例对象可以registerReceiver和sendBroadcast(intent)

注意事项: 只能通过动态注册的方式,静态注册主要是想让我们没打开程序时也能收到广播,但是发送广播时,程序肯定启动,就没必要使用静态注册

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private  NetworkChangeReceiver nevt;private LocalBroadcastManager lbm;@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;});lbm = LocalBroadcastManager.getInstance(this);IntentFilter iff= new IntentFilter();iff.addAction("android.intent.action.pp");nevt = new NetworkChangeReceiver();lbm.registerReceiver(nevt,iff);@SuppressLint({"MissingInflatedId", "LocalSuppress"}) View view = findViewById(R.id.button);view.setOnClickListener(this);}

实例总结:

  1. 如果有提示牌,记得用show来调用;

  2. 在配置xml文件中,主活动必须设置为可以由外部应用来调用

android:exported="true"

  1. 总体的思路:先化个登录界面的ui,然后写登录界面的活动:从文本框里获取字符串比较,如果成功的话就跳转到下一个活动,再写主活动,在主活动中,设置按钮,发送广播;在定义广播接收器,BasicActivity:因为必须要让所有的活动都可以接受到,这个一开始就先写,因为效果是关闭,所以ActivityCollector也必须先写;

 以上的实例总结是我个人的学习总结,各位可用于知识点的复习,如果不需要可跳过;

 好啦,就到这里!

http://www.lryc.cn/news/600688.html

相关文章:

  • golang实现一个定时引擎,功能包括按照corntab的时间任务实时增加、修改、删除定时任务
  • 常见sql深入优化( 二)
  • 一文学会c++list
  • 激光雷达-相机标定工具:支持普通相机和鱼眼相机的交互式标定
  • 二叉搜索树(Binary Search Tree)详解与java实现
  • Linux 如何统计系统上各个用户登录(或者登出)记录出现的次数?
  • Android-三种持久化方式详解
  • 摘录-打造第二大脑
  • J2EE模式---表现层集成模式
  • C++ TAP(基于任务的异步编程模式)
  • Web后端进阶:springboot原理(面试多问)
  • React入门学习——指北指南(第五节)
  • JavaScript手录06-函数
  • 【RK3568 PWM 子系统(SG90)驱动开发详解】
  • 数据赋能(336)——技术平台——智能化运营
  • Java动态调试技术原理
  • 【RocketMQ】一分钟了解RocketMQ
  • 告别复杂配置!Spring Boot优雅集成百度OCR的终极方案
  • Windows 平台源码部署 Dify教程(不依赖 Docker)
  • 《C++ list 完全指南:从基础到高效使用》
  • Linux——线程同步
  • InvokeRepeating避免嵌套调用
  • C++编程学习(第16天)
  • 7月26日京东秋招第一场第一题
  • 【第二章-数据的表示和运算】
  • 基于java的在线教育平台管理系统、在线学习系统的设计与实现
  • 【机器学习-2】 | 决策树算法基础/信息熵
  • 背包问题及 LIS 优化
  • 【Ubuntu】发展历程
  • 排序算法,咕咕咕