EventBus
是一个用于简化组件间通信的开源库,它使用发布-订阅
模式(Pub-Sub)来实现事件的传递。
在Android开发中,不同的组件(例如Activity、Fragment、Service等)之间可能需要进行通信,例如一个组件发送一个事件,而其他组件可以订阅并接收该事件。这种通信方式可以帮助组件之间解耦,使代码更加清晰和可维护。
EventBus是一款针对Android优化的
发布-订阅
事件总线。其优点开销小,代码更优雅。如果在
Fragment
和Fragment
的交互,使用广播来处理,代码量大,并且效率不高,而且传递的数据是实体Bean类的话,需要序列化,那么成本就会变得很高。
使用EventBus可以实现以下功能:
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
@Subscribe
注解来标识订阅的方法(3.0之后),并且满足:方法必须是公共的(public)。
方法只能有一个参数,参数类型是订阅的
事件类
。方法可以有任意的返回类型。
@Subscribe
public void onMessageEvent(MessageEvent event) {
String message = event.getMessage();
// 处理接收到的事件
}
post()
方法来发布事件。EventBus.getDefault().post(new MessageEvent("Hello EventBus!"));
发布事件后,EventBus会将事件发送给所有订阅了该事件的订阅者,订阅者会根据事件的类型和参数来执行相应的方法来处理事件。
当使用EventBus进行组件间通信时,可以采取以下详细步骤:
implementation 'org.greenrobot:eventbus:3.2.0'
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Subscribe
public void onMessageEvent(MessageEvent event) {
String message = event.getMessage();
// 处理接收到的事件
}
需要注意的是,订阅事件的方法名可以自定义,但需要保证方法是公共的(public),且只有一个参数。
EventBus.getDefault().post(new MessageEvent("Hello EventBus!"));
tips:如果运行出现异常
Subscriber class xxx and its super classes have no public methods with the @Subscribe annotation
,请尝试关闭R8压缩:buildTypes { release { minifyEnabled false .... } }
Subscribe有三个参数(可选):threadMode
、boolean sticky
、int priority
设置线程模型:如果需要在特定的线程中执行订阅方法,可以在订阅方法上添加线程模型注解(ThreadMode)。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
// 在主线程中执行
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessageEvent(MessageEvent event) {
// 在后台线程中执行
}
EventBus提供了四种线程模型:
默认线程模型(
POSTING
): 默认线程模型是EventBus的默认行为。在该模型中,事件发布和订阅者方法的执行在同一个线程中完成(发送事件和接收事件同一线程)。主线程模型(
MAIN
): 保证了事件的订阅者方法在主(UI)线程中执行。如果事件是在子线程中发布的,EventBus会将订阅者方法的执行切换到主线程。使用主线程模型可以确保订阅者方法中的UI操作在主线程中执行,避免了多线程操作UI的问题。后台线程模型(
BACKGROUND
): 后台线程模型保证了事件的订阅者方法在后台线程中执行,即使事件是在主线程(UI线程)或其他子线程中发布的。EventBus会为每个订阅者方法创建一个单独的后台线程,并在该线程中执行方法。可以避免在订阅者方法中执行耗时操作导致主线程阻塞的问题。异步线程模型(
ASYNC
): 异步线程模型是最灵活的线程模型,它保证了事件的订阅者方法在一个单独的线程中执行。无论事件是在主线程还是其他子线程中发布的,EventBus都会为每个订阅者方法创建一个单独的线程,并在该线程中执行方法,同时禁止UI更新操作。
黏性(sticky
)事件是一种特殊类型的事件,它在事件发布后会一直保存在EventBus的内存中,直到被消费或手动删除。默认为false
使用黏性事件可以实现以下功能:
订阅者方法会在订阅者注册后立即执行,并接收到最新的黏性事件。如果订阅者注册时,黏性事件已经存在,那么订阅者方法会立即执行并接收到该事件。
需要注意的是,使用黏性事件时要谨慎处理内存管理问题,避免事件过多导致内存泄漏或占用过多内存的情况。在不再需要黏性事件时,可以使用removeStickyEvent方法手动删除。
EventBus的@Subscribe注解可以使用priority
属性来设置订阅者方法的优先级。优先级决定了订阅者方法在事件发布时的执行顺序。
优先级是一个整数值,数值越小,优先级越高。默认情况下,优先级为0,所有订阅者方法的优先级相同。当设置priority属性时,数值越小,优先级越高。
如果优先级相同的订阅者方法存在,EventBus会根据注册的顺序来确定执行顺序。先注册的订阅者方法会先执行。
为了确保代码的健壮性,可以在订阅方法上添加异常处理注解(@Subscribe,throwable = true),以捕获并处理订阅方法执行过程中可能发生的异常。
@Subscribe(throwable = true)
public void onMessageEvent(MessageEvent event) {
// 处理事件,捕获可能发生的异常
}