说到广播,可能大家都用的比较少了吧,但是作为四大组件的一员,面试中还是少不了此类问题,今天的三问一起来回顾下吧:
1)注册方式:
Androidmanifest.xml
中注册receiver
标签即可,相关标签含义如下:<receiver
//能否接收其他 App 发出的广播
android:exported=["true" | "false"]
//继承BroadcastReceiver子类的类名
android:name=".mBroadcastReceiver"
//具有相应权限的广播发送者发送的广播才能被此 BroadcastReceiver 所接收
android:permission="string"
// BroadcastReceiver 运行所处的进程
android:process="string" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
registerReceiver()
进行注册,注意在页面销毁时候调用 unregisterReceiver()
进行注销,建议在onResume() 注册,并在 onPause()
进行注销。因为onStop等方法可能不会执行。2)生命周期:
BroadcastReceiver的生命周期很简单,发送事件后,收广播方调用onReceive方法,执行完毕后,对象被销毁,这就是一整个流程。要注意的是onReceive()
方法在10 秒内没有执行完毕, Android 会认为该程序无响应,所以onReceive()
方法不能执行耗时操作。
先说说BroadcastReceiver
的内部原理:大家都知道BroadcastReceiver
是一个系统级的广播,意思是手机里所有的app都能监听和发送,所以BroadcastReceiver
肯定是一个跨进程的通信,所以它的原理其实就是通过Binder机制
形成订阅关系,采用了设计模式中的观察者模式。包括订阅方和发送方以及消息中心,这个消息中心也就是AMS
,进行消息的跨进程处理。
我觉得有四种类型比较重要:
无序广播
,也就是默认的广播类型,无序广播对所有的广播接收者而言,是无序的。也就是说,所有接收者无法确定接收时序的顺序,这样也导致了,无序广播无法被停止。当它被发送出去之后,它将通知所有这条广播的接收者,直到没有与之匹配的广播接收者为止。有序广播
,通过 Context.sendOrderedBroadcast() 方法来发送。它可以允许接收者设定优先级,它会按照接收者设定的优先级依次传播。而高优先级的接收者,可以对广播的数据进行处理或者停止掉此条广播的继续传播。广播会先发送给优先级高 (android:priority) 的 Receiver,而且这个 Receiver 有权决定是继续发送到下一个 Receiver 或者是直接终止广播。粘性广播
,它采用 Context.sendStickyBroadcast() 方法进行发送广播。它被发出去之后,会一直滞留在系统中,直到有与之匹配的接收者,才会将其发出去。本地广播
,也就是LocalBroadcastManager类,使用 LocalBroadcastManager.getInstance(Context context) 方法获取到,它会保证广播只在app内进行传播。我觉得对于应用内的事件传播,EventBus基本可以替代广播了。EventBus
主要有以下优点:
相比之下EventBus的缺点就是不能跨进程,如果要使用跨进程功能的EventBus也有,HermesEventBus
,集成了Hermes和EventBus两个库,内部通信用EventBus,跨进程用的Hermes。所以就有了可以跨进程的HermesEventBus
。项目地址:https://github.com/Xiaofei-it/HermesEventBus
https://juejin.im/post/6844903507695239182