本篇文章共同学习EventBus3.0的使用方法。
EventBus 用于发布/订阅事件总线,简化了应用程序内各组件间、组件与后台线程间的通信。优点是开销小,代码更优雅,以及将发送者和接收者解耦。
一、EventBus的三要素
- Event:事件,可以是任意类型的对象。
- Subscriber:事件订阅者。被@Subscribe注解的方法即为事件处理方法,并且由参数threadMode指定线程模型(默认为ThreadMode.POSTING),四种线程模型下面会讲到。
- Publisher:事件发布者,可以在任意线程任意位置发送事件,直接调用EventBus.getDefault().post(event)方法。根据event参数的类型,会自动调用订阅该event的函数。
二、EventBus的四种ThreadMode
-
POSTING(默认)
发布事件和接收事件在同一个线程。
事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。 -
MAIN:
事件的处理会在UI线程中执行。
同样,事件处理时间不能太长,否则会引起ANR。 -
BACKGROUND
如果发布事件在UI线程,那么接收事件会在新的线程中运行。
如果发布事件在子线程,那么接收事件在同一线程执行。
在此事件处理函数中禁止进行UI更新操作。 -
ASYNC
无论事件在哪个线程发布,接收事件都会在新建的子线程中执行。
此事件处理函数中禁止进行UI更新操作。
三、EventBus基本用法
- 添加依赖库
implementation 'org.greenrobot:eventbus:3.1.1'
- 获取EventBus对象
EventBus.getDefault()
- 自定义事件类
public class MessageEvent {
public int event;
public String message;
public Object object;
public MessageEvent(int event) {
this.event = event;
}
public MessageEvent(int event, String message) {
this.event = event;
this.message = message;
}
public MessageEvent(int event, String message, Object object) {
this.event = event;
this.message = message;
this.object = object;
}
}
- 找到订阅时机,注册事件
EventBus.getDefault().register(subscriber); // subscriber类型是Object,即传入订阅的类
- 发送事件
EventBus.getDefault().post(messageEvent);
- 事件处理方法
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEventTest(MessageEvent messageEvent) {
int event = messageEvent.event;
// 事件处理...
}
- 取消事件订阅
EventBus.getDefault().unregister(subscriber);
四、代码应用
- 自定义事件类沿用上面的 MessageEvent 类
- 自定义MyEventBus,集成 注册/注销事件、事件处理方法等。
public class MyEventBus {
public static final String TAG = "MyEventBus";
public static MyEventBus instance;
public static final int EVENT_UPDATE = 1;
public static MyEventBus getInstance() {
if (instance == null) {
synchronized(MyEventBus.class) {
if (instance == null) {
instance = new MyEventBus();
}
}
}
return instance;
}
// 注册事件
public void register() {
EventBus.getDefault().register(this);
}
// 取消注册事件
public void unregister() {
EventBus.getDefault().unregister(this);
}
/**
* 事件处理方法,根据指定的threadMode,将在后台线程执行,因此不能进行UI操作
*/
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEventBackground(MessageEvent messageEvent) {
int event = messageEvent.event;
switch (event) {
case EVENT_UPDATE:
...
break;
}
}
}
- 比如在Activity的 onCreate() 注册事件,点击按钮发送事件,onDestroy() 注销事件
@Override
protected void onCreate() {
MyEventBus.getInstance().register(this);
}
public void clickPostEvent(View view) {
MessageEvent event = new MessageEvent(EmmEventBus.EVENT_UPDATE);
EventBus.getDefault().post(event);
}
@Override
protected void onDestroy() {
MyEventBus.getInstance().unregister(this);
}
五、EventBus3.0粘性事件
除了上面讲的普通事件外,EventBus还支持发送黏性事件,即:发送事件 -> 订阅事件 -> 处理事件。
粘性事件的写法,仅有以下的不同:
// 粘性事件处理方法,增加属性 sticky = true
@Subscribe(threadMode = ThreadMode.BACKGROUND,sticky = true)
public void onEventBackground(MessageEvent messageEvent) {
...
}
// 发送粘性事件
EventBus.getDefault().postSticky(new MessageEvent(2));
版权声明:本文为JoesaCSDN原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。