Broadcast

Broadcast

Broadcast概念

1. 定义

​ Broadcast(广播)是一个全局的监听器,属于Android四大组件之一,是一种广泛运用的在应用程序(APP)之间传输信息的机制。而BroadcastReceiver(广播接收器)是对发送出来的 广播进行过滤接受并响应的一类组件。

2. 应用场景

  1. Android不同组件间的通信(同一应用内 / 不同应用间)
  2. 多线程通信
  3. 与 Android 系统在特定情况下的通信
  4. 接收系统的状态信息

3. 生命周期

在这里插入图片描述

​ BroadcastReceiver 生命周期非常短暂,发送广播时创建,onReceive()方法结束之后销毁

4. 使用要素

  1. Broadcast (广播) – 用于发送广播
  2. BroadcastReceiver (广播接收器) – 用于接受广播
  3. Intent (意图) – 用于保存广播相关信息的媒介

Broadcast类型

1. 广播类型

  1. 从类型上可以分为有序广播和标准广播两大类
  2. 从广播接收器的注册方法上可以分为静态注册和动态注册
  3. 从发送方式上可以分为普通广播、有序广播、粘性广播、本地广播…
  4. 从所属队列上可以分为前台广播、后台广播

2. 事例

  1. 有序广播
    在这里插入图片描述
  2. 标准广播
    在这里插入图片描述

3. 注册

  1. 静态注册:通过新建Broadcast Receiver文件AndroidStudio会自动在AndroidManifest文件中注册

    		<receiver
                android:name=".MyReceiver"
                android:enabled="true"
                android:exported="true">
            </receiver>
    

    Broadcast Receiver文件为

    public class MyReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"MyReceiver",Toast.LENGTH_SHORT).show();
        }
    }
    

    然后在需要发送广播的地方进行

    //静态注册
            Intent intent1 = new Intent();
            intent1.setClassName(getPackageName(),"com.example.broadcasttest.MyReceiver");
            sendBroadcast(intent1);
    

    然后在MainActivity中进行实例化

    private MyReceiver myReceiver;
    
    myReceiver = new MyReceiver();
    
  2. 动态注册:和静态广播的创建BroadcastRecevier类似,新建一个BroadcastReceiver子类,通过extends BroadcastReceiver类

    private class LightReceiver extends BroadcastReceiver{
    
            @Override
            public void onReceive(Context context, Intent intent) {
                /*Bundle extras = intent.getExtras();
                Light light = (Light) extras.get("light1");*/
                Light light = intent.getParcelableExtra("light1");
                Log.d(TAG, "onReceive: " + light);
            }
        }
    

    发送广播

    //动态注册
            Intent intent = new Intent();
            intent.setAction("com.example.broadcasttest.LightService");
            intent.putExtra("light1",new Light("111",true));
            sendBroadcast(intent);
    

    由于动态广播是动态注册的,需要在类中进行初始化的声明,和AndroidManifest.xml中的 类似,在onCreate中实现注册:

    IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction("com.example.broadcasttest.LightService");
            mLightReceiver = new LightReceiver();
            registerReceiver(mLightReceiver,intentFilter);
    

    在onDestory中进行反注册

    unregisterReceiver(mLightReceiver);
    

4. Android的序列化

在这里有必要说明一下Android的序列化,不同于Java的实现Serializable接口,Android实现的是Parcelable接口

public class Light implements Parcelable {
    private String frequency;
    private boolean state;

    public Light(String frequency, boolean state) {
        this.frequency = frequency;
        this.state = state;
    }

    protected Light(Parcel in) {
        frequency = in.readString();
        state = in.readByte() != 0;
    }

    public static final Creator<Light> CREATOR = new Creator<Light>() {
        @Override
        public Light createFromParcel(Parcel in) {
            return new Light(in);
        }

        @Override
        public Light[] newArray(int size) {
            return new Light[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(frequency);
        dest.writeByte((byte) (state ? 1 : 0));
    }

    @Override
    public String toString() {
        return "Light{" +
                "frequency='" + frequency + '\'' +
                ", state=" + state +
                '}';
    }
}

这里就不需要实现构造器,实现get,set方法,只需要实现Parcelable接口的方法即可。在定义实体类的时候直接通过如下代码实现

new Light("111",true)

当在Intent中获取时,只需要调用getParcelableExtra方法即可直接返回实体类数据。

5. 注册和反注册

  1. 注册与反注册广播方法要成对出现,重复注册、重复注销也不允许
  2. 调用Context注册,就要用Context反注册。而不能直接调用unregisterReceiver(mReceiver)

在这里插入图片描述
5. unregisterReceiver(mReceiver)的作用:在Android开发中,在不进行反注册时,在关闭应用后,广播会一直处于接受状态,导致占用内存越来越大;而进行反注册后,则会结束广播,使得内存回收。

6. 有序广播与无序广播

在这里插入图片描述

7. 广播超时

  1. 并行队列中的广播的分发是循环取出每一个广播,直接分发,不需要等待客户端的反馈,所以并行队列中的广播分发很快
  2. 串行队列中的广播必须要等待前面的BroadcastReceiver执行完成后才会分发下一个,如果客户端的BroadcastReceiver运行在主线程,但是主线程又很繁忙,就有可能导致超时。
  3. 并行队列中的广播不存在超时概念,只有串行队列中的广播才会超时
  4. 存在静态注册的广播接收器的普通广播或有序广播
  5. 存在动态注册的广播接收器的有序广播

8. 本地广播LocalBroadcastReceiver

  1. LocalBroadcastReceiver与BroadcastReceiver区别:
    1. BroadcastReceiver是针对应用间、应用与系统间、应用内部进行通信的一种方式
    2. LocalBroadcastReceiver仅在自己的应用内发送接收广播,也就是只有自己的应用能收到,数据更加安全广播只在这个程序里,而且效率更高。
  2. LocalBroadcastReceiver不能静态注册,只能采用动态注册的方式。
  3. 使用:
    1. 发送广播同时创建BroadcastReceiver:
    LocalReceiver mLocalReceiver = new LocalReceiver();
    Intent intent = new Intent();
    intent.setAction(ACTION);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 
    
    1. 注册广播:
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(ACTION);
    LocalBroadcastManager.getInstance(this)
    .registerReceiver(mLocalReceiver, intentFilter);
    
    1. 反注册广播
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalReceiver);
    

Broadcast时序

  1. 普通广播(Normal Broadcast)
    1. 无视优先级,动态广播接收器优先于静态广播接收器
    2. 同优先级的同类广播接收器:
      1. 静态:先扫描的优先于后扫描的
      2. 动态:先注册的优先于后注册的
  2. 有序广播(Ordered Broadcast)
    1. 发送出去的广播被广播接收者按照先后顺序接收
      1. 优先级高的先接收(不分静态和动态)
      2. Priority属性相同者,动态注册的广播优先
    2. 特点:
      1. 接收广播按顺序接收
      2. 先接收的BroadcastReceiver可以对广播进行截断,那么后接收的BroadcastReceiver不能再接收到此广播
      3. 先接收的BroadcastReceiver可以对广播进行修改,那么后接收的BroadcastReceiver将接收到被修改后的广播

Broadcast参数

  1. Intent putExtra
    在这里插入图片描述

    Intent intent = new Intent();
            intent.setAction("com.example.broadcasttest.LightService");
            intent.putExtra("light1",new Light("111",true));
            sendBroadcast(intent);
    
  2. Intent getExtra
    在这里插入图片描述

    Light light = intent.getParcelableExtra("light1");
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

立花泷える宫水三叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值