当前位置: 首页 > 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.dtcms.com/a/299978.html

相关文章:

  • 零拷贝应用场景
  • 【Spring AI】大模型服务平台-阿里云百炼
  • 基于cooragent的旅游多智能体的MCP组件安装与其开发
  • javaSE 6
  • connect系统调用及示例
  • Go-Elasticsearch v9 安装与版本兼容性
  • Docker常用命令详解:以Nginx为例
  • 求hom_math_2d的角度值
  • Aerospike架构深度解析:打造web级分布式应用的理想数据库
  • JS实现数字变化时,上下翻滚动画效果
  • 本地部署智能家居集成解决方案 ESPHome 并实现外部访问
  • 五分钟系列-文本搜索工具grep
  • 【工具】好用的浏览器AI助手
  • 【MySQL】VARCHAR(10) 和 VARCHAR(100) 的区别
  • 大模型蒸馏(distillation)---从DeepseekR1-1.5B到Qwen-2.5-1.5B蒸馏
  • 拒绝SQL恐惧:用Python+pyqt打造任意Excel数据库查询系统
  • C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(四)
  • 丝杆升降机应用在食品机械行业有什么特殊的要求吗
  • Java BeanUtils 类详解:作用、语法与示例
  • springboot 基于签名的安全通信
  • 深入解析YARN中的FairScheduler与CapacityScheduler:资源分配策略的核心区别
  • Aerospike Java客户端进阶:对象映射与Spring Data集成实战
  • spring Could 高频面试题
  • 【科普】java和html和lvgl生成页面有什么区别,还有什么方法可以生成?
  • 数据库HB OB mysql ck startrocks, ES存储特点,以及应用场景
  • 通过服务启动应用的流程(类似SystemUi启动流程)
  • Linux笔记5——常用命令-4
  • 深入浅出学习 KNN 算法:从原理到数字识别实践
  • 【Linux庖丁解牛】— 日志进程池 !
  • 大模型系列——Dify:知识库与外部知识库