Broadcast:Android中实现组件及进程间通信

news/2024/9/21 1:33:48 标签: android, broadcast, android studio, java

目录

一,Broadcast和BroadcastReceiver

1,简介

2,广播使用

二,静态注册和动态注册

三,无序广播和有序广播

1,有序广播的使用

2,有序广播的截断

3,有序广播的信息传递

四,本地广播与全局广播

1,本地广播的使用


一,Broadcast和BroadcastReceiver

1,简介

        broadcast是Android提供的一种广播机制,用于组件或进程(即应用)间通信,同时也是Android四大组件之一;

        广播broadcast由两部分组成:发送者和接收者。发送者可以是Activity,Service等,广播的接收者为BroadcastReceiver,也就是广播接收器;

2,广播使用

broadcast的使用基本分为四步:

  1. 创建BroadcastReceiver类;
  2. 注册BroadcastReceiver;
  3. 发送广播;
  4. 解除注册;

(1)创建BroadcastReceiver子类重写onReceive方法。onReceive方法接收两个参数:context和intent,context为发送者的上下文,intent是发送者发送过来的信息;

java">public class MyBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "MyBroadcastReceiver" + " onReceive: 收到了广播消息");
    }
}

(2)注册接收器,接收器的注册方式分为静态注册和动态注册两种方式,这里使用动态注册方式。注册时需要配置过滤器,并且设置action,这里的action表示该注册器能够接收到包含该action的广播;

java">private void registerTheReceiver() {
    //配置过滤器,设置action
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(TextUtil.ACTION_SEND_RESULT);
    //注册接收器
    registerReceiver(broadcastReceiver, intentFilter);
}

(3)发送广播,与其他四大组件(Activity,Service)相同,也是通过intent来发送广播,通过设置action,标识该广播可被哪些接收器接收到,通过putExtra来传递额外信息;

java">//设置信息
Intent intent = new Intent();
intent.setAction(TextUtil.ACTION_SEND_RESULT);
intent.putExtra(TextUtil.KEY_RESULT, "这是广播1");
//发送广播
sendBroadcast(intent);

(4)解除注册,应当在合适的地方解除接收器的注册;

java">@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i(TAG, "onDestroy: ");
    //解除注册
    unregisterReceiver(broadcastReceiver);
}

二,静态注册和动态注册

        广播接收器有两种注册方式:在Manifest文件中注册java代码中注册,我们称在Manifest文件中注册为静态注册,在java代码中注册为动态注册。 上面使用的方式即为动态注册,下面为静态注册方式;

(1)静态注册前同样需要先创建接收器类,然后在Manifest文件中指明接收器的类名,可以通过<intent-filter>标签来配置过滤器,并设置action;

        静态注册的广播一般用于在应用启动时自动接收待定事件,比如系统启动,网络状态变化和电池状态变化等;

常见的广播类型(Action):

三,无序广播和有序广播

无序广播:接收器接收到的广播没有先后顺序,几乎同时收到;

有序广播:接收器按优先级顺序接收广播,同一时刻只能有一个接收器接收到广播;

简单来说就是广播可以设置优先级,然后就可以按顺序接收到广播,设置了优先级的广播称为有序广播,没有设置的称为无序广播,普通广播为无序广播; 

1,有序广播的使用

        通过IntentFilter过滤器的setPriority方法设置优先级,数值范围一般在-1000~1000之间,数值越大,优先级越高,有序广播通过sendOrderedBroadcast方法发送;

注册三个接收器,依次设置优先级,那么接收到的顺序应为3, 2, 1;

java">private void registerMyReceiver() {
    IntentFilter intentFilter = new IntentFilter(TextUtil.ACTION_SEND_RESULT);
    IntentFilter intentFilter2 = new IntentFilter(TextUtil.ACTION_SEND_RESULT);
    IntentFilter intentFilter3 = new IntentFilter(TextUtil.ACTION_SEND_RESULT);

    //设置优先级
    intentFilter.setPriority(100);
    intentFilter2.setPriority(101);
    intentFilter3.setPriority(102);

    registerReceiver(myBroadcastReceiver, intentFilter);
    registerReceiver(myBroadcastReceiver2, intentFilter2);
    registerReceiver(myBroadcastReceiver3, intentFilter3);
}
java">Intent intent = new Intent();
intent.setAction(TextUtil.ACTION_SEND_RESULT);
intent.putExtra(TextUtil.KEY_RESULT, "这是广播2");
//有序广播的发送
sendOrderedBroadcast(intent, null);

运行结果如下,可以看到接收顺序确实为3, 2, 1;

2,有序广播的截断

        在接收器中调用abortBroadcast方法即可阻断有序广播的传递 ,截断后广播不在向下传递,类似于Android的事件分发;

        以上面的例子为基础,我们在接收器2中截断广播,那么预期结果应为接收器3, 2可以接收到广播,1接收不到;

java">public class MyBroadcastReceiver2 extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "MyBroadcastReceiver2" + " onReceive: 收到广播消息");
        abortBroadcast(); //有序广播的截断
    }
}

运行结果如下,可以看到接收器1没有接收到广播:

3,有序广播的信息传递

        在有序广播的传递过程中,可以通过一系列方法来传递一些信息,上游接收器通过这些方法来向下游传递额外信息:

java">//传递Bundle信息

setResultExtras(Bundle);

//传递字符串信息
setResultData(String);

//传递int型信息
setResultCode(int);

//同时传递int, String, Bundle型数据
setResult(int, String, Bundle);

下游接收器通过对应的get方法来获取信息:

java">//获取Bundle信息
getResultExtras(true);//true表示如果传递过来的数据为空,则返回一个空的Map

//获取int型信息
getResultCode();

//获取String型信息
getResultData();

         例如我们在接收器3中向下游传递一些信息,因为接收器2的优先级小于接收器3,所以可以在接收器2中接收到传递的信息:

java">public class MyBroadcastReceiver3 extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        //向下游传递额外信息
        Bundle bundle = intent.getExtras();
        bundle.putString("name", "MyBroadcastReceiver3" + " 喜多郁代");
        setResultExtras(bundle);
        Log.i(TAG, "MyBroadcastReceiver3" + " onReceive: 收到静态广播消息");
    }
}
java">public class MyBroadcastReceiver2 extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = getResultExtras(true);//true表示如果传递过来的数据为空,则返回一个空的Map
        String name = bundle.getString("name");
        Log.i(TAG, "发件人: " + name + " " + "收件人: " + "MyBroadcastReceiver2");
        Log.i(TAG, "MyBroadcastReceiver2" + " onReceive: 收到静态广播消息");
    }
}

运行结果如下: 

四,本地广播与全局广播

本地广播:仅在本app内部传播,其他app接收不到,保证了数据的安全性;

全局广播:可以在整个手机所有app之间传播,会有安全性问题,普通广播默认是全局广播;

本地广播的注册,发送和解除注册都需要通过LocalBroadcastManager类来完成,使用LocalBroadcastManager需要添加依赖:

implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'

 另外,本地广播只能使用动态注册的方式,因为静态注册一般用于在应用启动时自动接收待定事件,而这些广播一定是全局广播;

1,本地广播的使用

(1)创建接收器,还是常规操作:

java">public class MyLocalBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyLocalBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "onReceive: 收到了本地广播");
    }
}

(2)通过LocalBroadcastManager类注册接收器:

java">//获取localBroadcastManager类
localBroadcastManager = LocalBroadcastManager.getInstance(this);

IntentFilter intentFilter1 = new IntentFilter(TextUtil.ACTION_SEND_LOACL_RESULT);

localBroadcastManager.registerReceiver(myLocalBroadcastReceiver, intentFilter1);

(3)发送广播:

java">Intent intent = new Intent();
intent.setAction(TextUtil.ACTION_SEND_LOACL_RESULT);
intent.putExtra(TextUtil.KEY_RESULT, "这是本地广播");
//发送本地广播
localBroadcastManager.sendBroadcast(intent);

(4)解除注册:

java">@Override
protected void onDestroy() {
    super.onDestroy();
    localBroadcastManager.unregisterReceiver(myLocalBroadcastReceiver);
}


http://www.niftyadmin.cn/n/5667963.html

相关文章

搜维尔科技:工程师已经解决OptiTrack捕捉过程中肘部不自然的弯曲

工程师已经解决OptiTrack捕捉过程中肘部不自然的弯曲 搜维尔科技&#xff1a;工程师已经解决OptiTrack捕捉过程中肘部不自然的弯曲

Windows环境下搭建MySQL主从同步实现读写分离

文章目录 前言读写分离的基本原理 环境介绍及说明主库my.ini初始配置创建用于同步的数据库和表 一、新增mysql从库1.复制mysql文件夹2.修改从库的my.ini3.安装到windows服务 二、在my.ini中配置主、从库相关参数1.主库新增配置参数不同版本参数不同问题 2.从库新增配置参数3.删…

视频单目标跟踪研究

由于对视频单目标跟踪并不是很熟悉&#xff0c;所以首先得对该领域有个大致的了解。 视频目标跟踪是计算机视觉领域重要的基础性研究问题之一&#xff0c;是指在视频序列第一帧指定目标 后&#xff0c;在后续帧持续跟踪目标&#xff0c;即利用边界框&#xff08;通常用矩形框表…

卷积神经网络经典模型架构简介

【图书推荐】《PyTorch深度学习与企业级项目实战》-CSDN博客 《PyTorch深度学习与企业级项目实战&#xff08;人工智能技术丛书&#xff09;》(宋立桓&#xff0c;宋立林)【摘要 书评 试读】- 京东图书 (jd.com) ImageNet是一个包含超过1 500万幅手工标记的高分辨率图像的数据…

MySQL索引知识个人笔记总结(持续整理)

本篇笔记是个人整理的索引知识总结&#xff0c;刚开始有点乱&#xff0c;后续会一直边学边整理边总结 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。就好比索引就是数据的目录 索引结构 Btree索引,Hash索引,Full-text索引&#xff0c;R-tree(空…

2、无线通信的主要特点

无线通信针对有线通信静态的缺点&#xff0c;以开放式来传递消息&#xff0c;打破了一定要有全封闭链路的限制&#xff0c;并将通信方式从静态推广到可移动的准动态。其代价是牺牲了全封闭的优质人造通道&#xff0c;来换取无须采用固定介质专用线路的开放式传输的灵活性&#…

一起对话式学习-机器学习03——模型评估与模型选择

【一】前言 这一部分其实已在第二节中介绍到&#xff0c;这节起到回顾归纳的作用。 【二】训练误差与测试误差 首先&#xff0c;在分类问题中&#xff0c;有误差率和准确率两个概念&#xff0c;二者和为1。 误差率&#xff1a;分类错误的样本数占总数的比例。 其次&#xff0c…

页面关键路径渲染详解

关键路径渲染 浏览器不会等待全部资源都下载完后才进行渲染&#xff0c;而是采用渐进式的渲染方式&#xff0c;本文就介绍一下这种渐进式的渲染方式。 当浏览器获取到用于呈现网页的资源后&#xff0c;通常就会开始渲染网页。那么究竟是在什么时候就会开始渲染&#xff1f; …