01 前言
当我们进行项目开发的时候,往往是需要应用程序的各组件、组件与后台线程间进行通信,比如在子线程中进行请求数据,当数据请求完毕后通过Handler或者是广播通知UI,而两个Fragment之间可以通过Listener进行通信等等。当我们的项目越来越复杂,使用Intent、Handler、Broadcast进行模块间通信、模块与后台线程进行通信时,代码量大,而且高度耦合。
02 什么是EventBus
进入官网,看看人家是怎么解释的:
EventBus allows publish-subscribe-style communication between components without requiring the components to explicitly register with one another (and thus be aware of each other). It is designed exclusively to replace traditional Java in-process event distribution using explicit registration. It is not a general-purpose publish-subscribe system, nor is it intended for interprocess communication.
大概的意思就是:EventBus能够简化各组件间的通信,让我们的代码书写变得简单,能有效的分离事件发送方和接收方(也就是解耦的意思),能避免复杂和容易出错的依赖性和生命周期问题。
03 关于EventBus的概述
三要素
- Event 事件。它可以是任意类型。
- Subscriber 事件订阅者。加上注解@subscribe()
- Publisher 事件的发布者。我们可以在任意线程里发布事件,一般情况下,使用EventBus对象,然后再调用post(Object)方法即可。
04 EventBus的基本用法
举个例子,我需要在一个Activity里注册EventBus事件,然后定义接收方法,这跟Android里的广播机制很像,你需要首先注册广播,然后需要编写内部类,实现接收广播,然后操作UI。所以,在EventBus中,你同样得这么做。
EventBus初始化并注册事件
@Configuration
@Log4j2
public class EventBusConfig {
@Bean(name = "eventBus")
public EventBus getEventBus() {
// 线程池配置
int threadCount = Runtime.getRuntime().availableProcessors() + 1;
BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("EventBus-schedule-pool-%d").build();
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount, threadFactory);
executorService.setRejectedExecutionHandler(new RejectedExecutionHandler() {
... 拒绝处理
});
// 异步事件总线
EventBus eventBus = new AsyncEventBus(executorService, new SubscriberExceptionHandler() {
... 省略处理方式
});
// 注册监听器
Reflections reflections = new Reflections("com.your.package", new MethodAnnotationsScanner());
Set methods = reflections.getMethodsAnnotatedWith(Subscribe.class);
if (null != methods) {
for (Method method : methods) { eventBus.register(AppContextHolder.getBean(method.getDeclaringClass()));
}
}
return eventBus;
}
自定义一个事件类
@Data
@AllArgsConstructor
public class RepayResultEvent {
/**
* 订单 id
*/
private Long borrowId;
/**
* 还款申请id
*/
private Long raId;
}
这个类就是一个Bean类,里面定义用来传输的数据的类型。
发送事件
// 发送事件
EventBus eventBus = (EventBus) AppContextHolder.getBean("eventBus");
eventBus.post(new RepayResultEvent(borrowId, applyId));
处理事件
@Slf4j
@Component
public class XXX {
@Subscribe
@AllowConcurrentEvents
public void handler(RepayResultEvent event) {
log.info("开始执行事件监听器: {}", event.toString());
... 处理逻辑
}
}
总结
经过这个简单的例子,我们发现EventBus使用起来是如此的方便,当我们的代码量变得很多的时候,使用EventBus后你的逻辑非常的清晰,并且代码之间高度解耦,在进行组件、页面间通信的时候,EventBus是一个不错的选择。