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

目录

一,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);
}
相关推荐
逊嘘5 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
帅得不敢出门10 分钟前
Gradle命令编译Android Studio工程项目并签名
android·ide·android studio·gradlew
morris13112 分钟前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
七星静香37 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员38 分钟前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU38 分钟前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea
stewie642 分钟前
在IDEA中使用Git
java·git
problc1 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
Elaine2023911 小时前
06 网络编程基础
java·网络
G丶AEOM1 小时前
分布式——BASE理论
java·分布式·八股