Github地址:https://github.com/greenrobot/EventBus
中文翻译参考:http://blog.csdn.net/poorkick/article/details/55099311
EventBus 是一个使用发布者/订阅者模式 并且低耦合的Android开源库。个人理解类似于Android中的观察者模式。详细介绍请看官方文档,本文重点想说明的 红色标记出来了。
来自Github的一张图
一,添加依赖
implementation 'org.greenrobot:eventbus:3.1.1'
二,注册 / 解除注册
//注册EventBus事件
EventBus.getDefault().register(this);
//解除注册
EventBus.getDefault().unregister(this);
三,准备消息类
public class MessageEvent {
private int id;
private String name;
public MessageEvent(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
四,发送消息
两种发送消息的方式(普通事件+粘性事件)
EventBus.getDefault().post(new MessageEvent(1,"test"));
EventBus.getDefault().postSticky(new MessageEvent(2,"Test"));
五,接收消息
@Subscribe 注解来定义订阅者方法
threadMode 确认线程模式
sticky 是否接受粘性事件
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void getEventBusMsg(MessageEvent event) {
switch (event.getId()){
case 1:
break;
case 2:
break;
}
}
一,ThreadMode: POSTING
订阅者将会在事件发布的线程中被调用。这是默认模式。事件的传递是同步完成的,一旦事件发布完成,所有的订阅者都将会被调用。由于完全避免了线程切换,这种模式的开销是最小的。所以,针对那些不需要主线程并且能在很短时间内完成的简单任务,我们推荐使用这种模式。这种模式下的事件处理方法必须快速返回,避免阻塞发布事件的线程,因为这个线程有可能是主线程。
二,ThreadMode: MAIN
订阅者将在Android的主线程(有时称为UI线程)中调用。 如果发布线程是主线程,则将直接调用事件处理方法(与ThreadMode.POSTING描述的同步)。 使用此模式的事件处理程序必须快速返回,以避免阻塞主线程。
三,ThreadMode: BACKGROUND
订阅者将在后台线程中调用。 如果发布线程不是主线程,事件处理程序方法将直接在发布线程中调用。 如果发布线程是主线程,EventBus使用单个后台线程来按顺序传递所有事件。 使用此模式的事件处理方法应尽快返回以避免阻塞后台线程。
四,ThreadMode: ASYNC
事件处理方法在单独的线程中调用。 这个线程总是独立于发布线程和主线程。 这种模式下,发布事件不会等待事件处理方法的执行结果。 如果事件处理方法的执行需要一些时间,则应该使用此模式,如网络访问。 避免同时触发大量长时间运行的异步处理方法以限制并发线程的数量。 EventBus使用线程池来有效地重用已完成任务的线程。
特点是不需要先订阅,就是在发送事件之后再订阅该事件也能收到该事件。例如已经发送了一个粘性事件,这时候再打开一个新的Activity或者Fragment,并在其中订阅了EventBus的消息,那么这个时候,粘性事件能够收到,而普通事件无法收到。
同一类型(消息类)的粘性事件只会保存一个,如果有多个一起发生,则只会保存最后一个类型的粘性事件
这里,我有看几篇文章都写得不是很清楚,都是两个方法一起使用,看了下官方文档,总结一下,如有错误,欢迎纠正。
最后一个粘性事件在注册时自动传递给匹配的订阅者,但有时手动检查粘性事件可能会更方便。
//粘性事件的获取
MessageEvent event = EventBus.getDefault().getStickyEvent(MessageEvent.class);
//判断是否存在
if(null != event){
//存在,先清除
EventBus.getDefault().removeStickyEvent(event);
//do something ...
}
或者,因为 方法removeStickyEvent是重载的:当你传入类时,它将返回先前持有的粘性事件。所以上面部分可以改进一下,当然用上面的方式,也完全没有问题
//粘性事件的获取
MessageEvent removeEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);
//判断是否存在
if(null != removeEvent){
//do something ...
}
Subscribe注解可以使用priority进行修饰,同一分派事件中,优先级越高,订阅方法越先处理。
@Subscribe(threadMode = ThreadMode.MAIN, priority = 1)
public void getEventBusMsg(MessageEvent event) {
EventBus.getDefault().cancelEventDelivery(event);
}
这里可以做一种类似 Android事件分发,可以使用设置优先级+取消事件分发,实现一个事件拦截。当然拦截后不会反向向上传递,只是拦截并处理掉该事件,结束。