概念

事件总线是对发布-订阅模式的一种实现。也就是当一个对象改变时,对所有依赖于其的对象进行通知和修改。

定义

事件(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更新操作。

 

 

优点

  • 使用简单
  • 快速且轻量

缺点

可能会造成接口的膨胀,特别是当程序要求大量形式各异的通知,而程序员没有做出良好的抽象时,代码中会包含大量的接口。