EventBus是一款Android下的发布/订阅事件总线机制。可以代替Intent、Handler、Broadcast等在Fragment、Activity之间传递消息。
优点:开销小,代码优雅。将发送者和接受者解耦。
3.0与2.x的区别
主要区别在订阅函数的不同
EventBus2.x中只暴露了四个方法供用户调用,分别是
- onEvent:该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
- onEventMainThread:不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
- onEventBackgroundThread:如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
- onEventAsync:无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.
EventBus3.0中必须使用注解,例如:
@Subscribe(threadMode = ThreadMode.Async, sticky = true, priority = 1)
public void firstEvent(FirstEvent event) {
Log.e("TAG", "Async" + Thread.currentThread().getName());
}
好处在于订阅函数可以随便起名字,其他与2.x没什么不同。<br/>这里Subscribe中的key需要解释一下含义,Subscribe中可以传三种值:
-
ThreadMode:这是个枚举,有四个值,决定订阅函数在哪个线程执行
- PostThread:事件发送者在哪个线程就执行在哪个线程。同2.x中的onEvent方法,默认值就是这个
- MainThread:订阅函数一定执行在主线程。同onEventMainThread方法
- BackgroundThread:如果是事件从子线程发出,订阅函数就执行在那个子线程,不会创建新的子线程;如果主线程发出事件,则创建子线程。同onEventBackgroundThread方法
- Async:一定创建子线程。同onEventAsync方法。
-
sticky:默认为false,如果为true,当通过
postSticky
发送一个事件时,这个类型的事件的最后一次事件会被缓存起来,当有订阅者注册时,会把之前缓存起来的这个事件直接发送给它。使用在比如事件发送者先启动了,订阅者还没启动的情况。 - priority:默认值为0。订阅了同一个事件的订阅函数,在ThreadMode值相同的前提下,收到事件的优先级。
Configuration用法:
当默认的EventBus不足以满足需求时,EventBusBuilder就上场了,EventBusBuilder允许配置各种需求的EventBus
例如1:
当没有subscribers的时候,eventbus保持静默:
EventBus eventBus = EventBus.builder().logNoSubscriberMessages(false)
.sendNoSubscriberEvent(false).build();
例如2:
配置异常:
默认情况下:eventbus捕获onevent抛出的异常,并且发送一个SubscriberExceptionEvent 可能不必处理
EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();
配置默认的eventbus单例
官方推荐:在application类中,配置eventbus单例,保证eventbus的统一
例如:配置eventbus 只在DEBUG模式下,抛出异常,便于自测,同时又不会导致release环境的app崩溃
EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();
Sticky Events用法:
前面说的一般的post event,正常流程,必须是先register,然后post event,handle event才能起作用。但是当我们post event时,还没有subcriber怎么办?但是又想后注册的subscriber,能收到消息,这时sticky event就开始大显身手了。
Warning:EventBus会把最后一个sticky event记录在内存中,然后分发给subscriber
来看下官方的Demo
1 post sticky event:
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
2 启动一个新的Activity,准备subs