EventBus is a publish/subscribe event bus for Android and Java.
1. 介绍
关于 EventBus 在开发中经常会选择使用它来进行模块间通信、解耦。
平常使用这个库只是很浅显的操作三部曲,register,post,unregister,来达到开发目的。
EventBus 是一个开源库,它利用发布/订阅者者模式来对项目进行解耦。它可以利用很少的代码,来实现多组件间通信。在 Android 领域十分有名,当然,它也能运用到 Java 领域。
官方网址:https://github.com/greenrobot/EventBus
2. 简单使用
2.1 引入依赖
<dependency>
<groupId>org.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>3.1.1</version>
</dependency>
在 EventBus 3.0 之后,EventBus 利用注解对 EventBus 的使用进行了简化,不再要求自定义的类必须实现某某接口,只要使用对应注解就行。
因此,不要使用 3.0 以下的版本。
2.2 事件类
EventBus 不强求事件类必须实现某某接口,或继承某某类。因此,像 String 这样的 JDK 自带的引用类型就可以直接充当事件类。
如果你需要自定义事件类,直接定义一个类即可:
public class MessageEvent {
}
最简单的自定义事件类可以像如上情况,事件类的【存在】就是有很大价值,哪怕它没有任何属性。
不过,考虑到事件对象会作为数据的容器/载体,在事件发送者和事件处理者之间传递信息,通常事件类中还是会根据需求定义一个或多数属性:
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
2.3 事件处理类
事件处理类是事件的接收者,或者说,它是事件发生后所要执行的代码。
之前提到过,EventBus 3.0 之后因为利用了注解,所有就不再要求事件处理类被必须实现某某接口,或继承某某类。
对于上面的以 String 类作为事件类,并没有去自定义事件类的情况,它对应的事件处理类会定义成如下形式:
public class StringEventHandler {
@Subscribe
public void onMessageEvent(String event) {
System.out.println("事件处理函数" + event);
}
}
上述代码有 2 点注意的地方:
-
类名和方法名可以任意,EventBus 对他们的命名没有要求。不过,按照一般的惯例,类名通常都是叫 XxxEventHandler,方法名都是叫:onEvent、onMessageEvent、handle 等约定熟成的名字。|
-
事件处理方法的参数是和事件处理类【遥相呼应】的。我们以 JDK 内置的 String 类作为事件类的话,那么 onMessageEvent 方法的参数那就必须是 String 类型。|
如果之前有自定义事件类,那么它对应的事件处理类会是如下形式:
public class MessageEventHandler {
@Subscribe
public void onMessageEvent(MessageEvent event) {
System.out.println("事件处理函数" + event);
}
}
参照上述的 2 点注意,看看这两个事件处理类有何不同之处。
2.4 发出事件
定义完事件类和事件处理类,相当于逻辑上做除了这样的一种设定:当 xxx 的时候,就会去执行 xxx 代码。
所以,我们需要去【触发】事件处理类中的处理方法的执行。
首先,我们需要<small>(在 main 方法中)</small>去创建并注册事件处理类的实例:
StringEventHandler handler = new StringEventHandler();
EventBus.getDefault().register(handler);
...
EventBus.getDefault().unregister(handler);
显而易见,unregister 是 register 的反向操作。
EventHandler 必须注册到 EventBus,否则,当你向 EventBus 发送 Event 时,EventBus 不知道要将这个 Event 交给哪个 Handler 处理,即,不知道去执行哪个 Handler 中的 @Subscribe 方法。
向 EventBus 发送消息,进而触发 EventHandler 方法的执行方式如下:
EventBus.getDefault().post("hello?");
EventBus.getDefault().post(new MessageEvent());
EventBus.getDefault().post(new MessageEvent("hello?"));
这里的三行代码分别对应上述的三种情况:
- 以 JDK 内置的 String 类作为消息类;
- 自定义消息类,但其中无属性;
- 自定义消息类,其中有属性。
在这里<small>(main 方法中)</small>,post()
方法的参数将会被 EventBus 传递到 EventHandler 中作为 @Subscribe 方法的入参。
3. 同步调用与异步调用
-
同步调用指的是:【调用者】与【被调者】在 同一个线程 中,那么只有被调者的方法执行结束,调用者才会继续执行;
-
异步调用指的是:【调用者】与【被调者】在 不同的线程 中,那么调用者无需等待被调者的方法的返回,即可继续执行。
EventBus 支持同步调用与异步调用两种方式。
默认情况下,EventHandler 的 @Subscribe 方法是同步调用:
@Subscribe
public void onEvent(String event) throws InterruptedException {
...
}
上面的 @Subscribe 等同于:
@Subscribe(threadMode = ThreadMode.POSTING)
表示的是 EventHandler 的 @Subscribe 方法与调用者在同一个线程中运行。
如果像实现异步调用可以使用:
@Subscribe(threadMode = ThreadMode.ASYNC)
<small>由于 EventBus 是 Android 领域的【著名】工具,而 Android 上线程的角色的划分更加细致,所以,你会发现 ThreadMode 的值会有很多,并非只有 POSTING 和 ASYNC 这两种。
如果我们在 Java Web App 领域使用它,我们面对的线程的角色的划分,要比 Android 更简洁清晰。因此,我们只需要关注 POSTING 和 ASYNC 两种即可。</small>
网友评论