一、简单介绍
EventBus是一种能够简化各组件间的通信,通过解耦发布者和订阅者简化Android事件传递用以代替Android传统的Intent,Handler,Broadcast或接口函数,在Fragment,Activity,Service线程之间传递数据,执行方法。
优势:
简化了组件间的通讯,是一种发布订阅设计模式(观察者设计模式)。
分离了事件的发送者和接受者。
- 在Activity、Fragment和线程中表现良好。
- 避免了复杂的和易错的依赖关系和生命周期问题。
- 使得代码更简洁,性能更好。
概念:
- Event 事件。它可以是任意类型。
- Subscriber 事件订阅者,使用需要加上注解@subscribe(),并且指定线程模型,默认是POSTING。
- Publisher 事件的发布者。我们可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。
线程模型:
- POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
- MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
- BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
- ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。
二、简单使用
1、添加依赖,EventBus网址。
implementation 'org.greenrobot:eventbus:3.1.1'
2、构造事件(Event)对象(发送消息类)。
/**
* Created by Active_Loser on 2018/9/20
* Content:简单的提示事件
*/
public class ToastEvent {
private String content;
public ToastEvent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
3、注册/解除事件订阅
在onCreate()中通过register(this)来表示该订阅者进行了订阅
EventBus.getDefault().register(this);
使用注解@Subscribe,处理相关操作
注意:
若在非UI线程,需要使用@Subscribe(threadMode = ThreadMode.MainThread)更新UI
设置优先级:@Subscribe(priority = 100)
@Subscribe
public void onToastEvent(ToastEvent event){ Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show();
}
在onDestory()方法中进行解除订阅。
EventBus.getDefault().unregister(this);
4、发送事件,发送消息
EventBus.getDefault().post(new ToastEvent("我是一个toast!"));
三、粘性事件
订阅在发布事件之后,但同样可以收到事件。订阅/解除订阅和普通事件一样,但是处理订阅的方法有所不同,需要注解中添加sticky = true。
@Subscribe(sticky = true)
public void onToastEvent(ToastEvent event){
Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show();
EventBus.getDefault().cancelEventDelivery(event);
}
}
当设置了sticky = true,在ToastEvent 的事件发布后,进行注册。依然能够接收到之前发布的事件。
EventBus.getDefault().postSticky(new ToastEvent("Toast,发个提示,祝大家新年快乐!"));
移除
EventBus.getDefault().removeStickyEvent(ToastEvent.class);
//移除所有粘性事件
EventBus.getDefault().removeAllStickyEvents();