Android 四大组件之BroadCastReceiver(广播)知识总结

一、广播的概念

广播(BroadCastReceiver)是安卓四大组件之一,用于安卓组件之间的通信,信息由广播发送者流向广播接收者。广播的使用一般有以下场景;

  • 同一 app 内部的不同组件之间的消息通信
  • 不同 app 之间的组件之间消息通信
  • Android 系统在特定情况下与App之间的消息通信

广播使用观察者模式,广播发布者和广播接收者分别为消息发布者和消息订阅者,其大致流程如下:

  1. 广播接收者通过 Binder 机制向 AMS(Activity Manager Service) 进行注册。
  2. 广播发送者通过 Binder 机制向 AMS 发送广播。
  3. AMS查找符合相应条件的广播接收者,并将广播发送到其消息队列中。
  4. 消息队列拿到此广播,回调 onReceive() 方法。

二、广播的分类

根据广播发送方式的不同,可以将广播分为以下几种类型:

2.1 无序广播(Normal Broadcast)

无序广播也叫普通广播,使用 sendBroadcast() 方法发送广播,广播可以发送给所有的广播接收者,广播接收者在接收广播时有以下顺序:

  1. 动态广播接收器优先于静态广播接收器
  2. 同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。

(编写 demo 进行测试时发现动态地后注册的反而先接受,不知道是为什么)

2.2 有序广播(Ordered broadcast)

有序广播使用 sendOrderedBroadcast() 方法发送广播,广播将按照事先设置好的优先级依次发送给广播接收者。广播接收者可以终止广播的继续传播;广播的接收者可以将数据放进广播中传递给后面的广播接收者。广播接收者在接收广播时有以下顺序:

  1. 优先级高的先接收
  2. 同优先级的广播接收器,动态优先于静态
  3. 同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。

2.3 粘性广播(Sticky Broadcast)

粘性广播使用 sendStickyBroadcast() 方法发送广播,发送粘性广播需要申请权限:

<uses-permission android:name="android.permission.BROADCAST_STICKY"/>

粘性广播一般用来确保重要的状态改变后的信息被持久保存,并且能随时广播给新的广播接收器。对于普通广播和有序广播,若广播发送者发送广播时广播接收者还未进行注册,则广播接收者无法再收到这个广播;而对于粘性广播,即使广播发送者发送广播时广播接收者还未进行注册,广播接收者会保留这条广播,当广播接收者注册时将此条广播发送给接收者,可以在接收到广播后调用 removeStickyBroadcast(intent) 移除该广播。

2.4 系统广播(System Broadcast)

安卓的大量系统事件都会对外发送标准广播,应用可以通过监听系统广播来实现对系统事件的响应。例如:手机开机、电池电量低、系统时间被改变等。更多的系统广播可见此博客

2.5 本地广播(Local Broadcast)

本地广播是在应用内部进行广播,不让其它应用参与,相比于使用全局广播添加限制实现本地广播的效果(从上述的广播大致流程可知全局广播有两次通过 Binder 跟 AMS 进行通信的步骤),Local Broadcast 更加安全和高效。关于本地广播的源码解读可以看此博客

三、广播的注册方式

3.1 静态注册

静态注册的示例如下:

<receiver android:name="com.example.broadcasttest.MainActivity$Receiver">
    <intent-filter>
        <action android:name="com.example.broadcasttest.update"></action>
    </intent-filter>
</receiver>

3.2 动态注册

动态注册的示例如下:

val receiver = MyReceiver()
val filter = IntentFilter()
filter.addAction("com.example.broadcasttest.update")
registerReceiver(receiver, filter)

注意:动态广播需要在使用后进行注销,一般在 onDestroy() 中注销。

unRegisterReceiver(receiver)

3.3 区别

  • 动态注册广播不是常驻型广播,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。
  • 静态注册一般持续到进程结束(应用关闭),如果想要在应用关闭后仍然可以接受广播,则需要在发送广播时给 intent 设置 flag,示例如下:
val intent = Intent("com.example.qingyunhuohuo.update")
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
sendBroadCast(sendIntent)

3.4 本地广播的注册

本地广播只能采用动态注册的方式,其注册实例如下:

val receiver = MyReceiver()
val filter = IntentFilter()
filter.addAction("com.example.broadcasttest.update")
LocalBroadcastManager.getInstance (this).registerReceiver(receiver, filter)

注意:本地广播也需要在使用后进行注销,一般在 onDestroy() 中注销。

LocalBroadcastManager.getInstance (this).unregisterReceiver(receiver)

猜你喜欢

转载自blog.csdn.net/qingyunhuohuo1/article/details/109600113