简介:
EventBus是一个用于Android和Java的开源库,使 publisher/subscriber模式实现解耦。EventBus使中间通信仅用几行代码就能解耦类,简化代码,移除依赖和加速应用开发。
优点:
- 简化组件之间的通信
- 解耦事件发送方和接收方
- 能够很好地处理UI工件(例如活动、片段)和后台线程
- 避免复杂和容易出错的依赖关系和生命周期问题
- 快;专为高性能而优化
- 很小(<50k jar)
- 在实践中是否被安装超过1亿次的应用程序所证明
- 具有高级特性,如交付线程、订阅者优先级等。
特性:
- 简单但功能强大:EventBus是一个小型库,具有超级容易学习的API。尽管如此,您的软件架构可能会从解耦组件中获益良多:订阅者在使用事件时并不知道发送者。
- 战斗测试:EventBus是最常用的Android库之一:数以千计的应用程序使用EventBus,包括非常流行的应用程序。超过10亿的应用程序安装说明了一切。
- 高性能:尤其是在Android上,性能很重要。对EventBus进行了大量的分析和优化;这可能是最快的解决方案。
- 方便的基于注释的API(不牺牲性能):只需将@Subscribe注释放到订阅方方法中。由于注释的构建时索引,EventBus在您的应用程序运行时不需要进行注释反射,这在Android上非常慢。
- Android主线程交付:当与UI交互时,EventBus可以在主线程中交付事件,而不管事件是如何发布的。
- 后台线程交付:如果订阅服务器执行长时间运行的任务,EventBus还可以使用后台线程来避免UI阻塞。
- 事件,订阅者继承:在EventBus中,面向对象范式应用于事件和订阅者类。假设事件类A是B的超类。B类型的已发布事件也将被发布给对A感兴趣的订阅者。
- 零配置:您可以立即使用代码中任何地方可用的默认EventBus实例启动。
- 可配置:要根据您的需求调整EventBus,您可以使用构建器模式调整它的行为。
接入
1、在你项目app的build.gradle中添加
implementation 'org.greenrobot:eventbus:3.1.1'
简单实用
1、定义一个event用于存储数据
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
2、准备订阅器:声明和注释订阅方法,可选地指定线程模式:
// This method will be called when a MessageEvent is posted (in the UI thread for Toast)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}
// This method will be called when a SomeOtherEvent is posted
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
doSomethingWith(event);
}
3、注册和注销你的订阅者。例如,在Android上,活动和片段通常应该根据它们的生命周期进行注册:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
4、发送event
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
高级特性 交付线程(线程模式)
EventBus可以为你处理线程,事件可以在不同于发布线程的线程中发布。常见的用例是处理UI更改,在Android中UI更改必须在UI(主)线程中。另一方面,网络或任何耗时任务都不能在主线程上运行,EventBus帮你处理这些任务并与UI线程同步(无需深入研究线程转换、使用AsyncTask等)。
1: POSTING
ThreadMode.POSTING将在发布事件的线程中调用订阅者(Subscribers)。这是TheadMode的默认值,事件交付是同步完成的,一旦发布完成,将调用所有订阅者(Subscribers)。这种ThreadMode意味着开销最小,因为他完全避免了线程切换。因此对于已知不需要主线程就可以在很短时间完成的简单任务,推荐使用这种模式。使用此模式的事件处理程序应快速返回,以避免阻塞可能是主线程的发布线程。例子:
// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
log(event.message);
}
2: MAIN
Thread.MAIN订阅者(Subscribers)将在Android的主线程中调用(有时称为UI线程)。如果发布线程是主线程,则将直接调用事件处理程序方法(与threadmode.post中描述的同步)。使用此模式的事件处理程序必须快速返回,以避免阻塞主线程。例子:
// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
3: MAIN_ORDERED
订阅者(Subscribers)将在Android的主线程中被调用。事件总是排队等待稍后交付给订阅者,因此对post的调用将立即返回。这使得事件处理的顺序更加严格和一致(因此命名为MAIN_ORDERED)。例如,如果您使用主线程模式在事件处理程序中发布另一个事件,第二个事件处理程序将在第一个事件处理程序之前完成(因为它是同步调用的——将其与方法调用进行比较)。使用MAIN_ORDERED,第一个事件处理程序将完成,然后在稍后的时间点调用第二个事件处理程序(只要主线程具有容量)。
使用此模式的事件处理程序必须快速返回,以避免阻塞主线程。例子:
// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
4: BACKGROUND
订阅者(Subscribers)将在后台线程中调用。如果发布线程不是主线程,则将在发布线程中直接调用事件处理程序方法。如果发布线程是主线程,则EventBus使用一个后台线程,该线程将按顺序交付所有事件。使用此模式的事件处理程序应尝试快速返回,以避免阻塞后台线程
// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
saveToDisk(event.message);
}
5: ASYNC
事件处理程序方法在单独的线程中调用。这总是独立于发布线程和主线程。发布事件永远不要等待使用此模式的事件处理程序方法。如果事件处理程序方法的执行可能需要一些时间,例如网络访问,则应使用此模式。避免同时触发大量长时间运行的异步处理程序方法来限制并发线程的数量。EventBus使用线程池有效地重用来自已完成的异步事件处理程序通知的线程。
// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
backend.send(event.message);
}