概念
事件总线是对发布-订阅模式的一种实现。也就是当一个对象改变时,对所有依赖于其的对象进行通知和修改。
定义
事件(Event):又可称为消息,本文中统一用事件表示。其实就是一个对象,可以是网络请求返回的字符串,也可以是某个开关状态等等。事件类型(EventType)指事件所属的 Class。
事件分为一般事件和 Sticky 事件,相对于一般事件,Sticky 事件不同之处在于,当事件发布后,再有订阅者开始订阅该类型事件,依然能收到该类型事件最近一个 Sticky 事件。
订阅者(Subscriber):订阅某种事件类型的对象。当有发布者发布这类事件后,EventBus 会执行订阅者的 onEvent 函数,这个函数叫事件响应函数。订阅者通过 register 接口订阅某个事件类型,unregister 接口退订。订阅者存在优先级,优先级高的订阅者可以取消事件继续向优先级低的订阅者分发,默认所有订阅者优先级都为 0。
发布者(Publisher):发布某事件的对象,通过 post 接口发布事件。
实例
1.
Activity中的不同的fragment之间需要进行通信,传统的做法是 将activity作为中介,Fragment A通过getActivity()获取宿主的Activity实例进而可以拿到Fragment B的实例,从而向Fragment B发送消息或者获取数据。好一点的做法是在Fragment中编写接口,让宿主Activity实现该接口,从而在Activity中实现不同Fragment之间的数据通信。
2.
多个Activity页面跳转和数据回传的问题,例如Activity A跳转到Activity B,接着跳转到ActivityC,在C中执行一系列操作之后,需要传递数据或者事件给Activity A,传统的做法是进行接口回调,这样不仅增加逻辑复杂性,而且增大页面间的耦合。
线程模式
- POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至可能会引起ANR。
- MAIN:事件的处理会在UI线程中执行,事件处理时间不能太长,长了会ANR。
- BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件的处理函数直接在发布时间的线程中执行。在此事件处理函数中禁止对UI进行更新操作。
- ASYNC:无论事件在哪个线程中发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。
优点
- 使用简单
- 快速且轻量
缺点
可能会造成接口的膨胀,特别是当程序要求大量形式各异的通知,而程序员没有做出良好的抽象时,代码中会包含大量的接口。