最近一直在使用handler来传递消息,同事提到了EventBus,所以来学一学,顺便记录一下。
一、什么是EventBus
Android Event Bus是一种用于在Android应用程序中实现事件通信的库。它允许不同组件(如Activity、Fragment、Service等)之间进行解耦的通信,以便它们可以在不直接相互引用的情况下进行通信。
二、如何使用
1.引入Event Bus库
implementation 'org.greenrobot:eventbus:3.2.0'
2.创建事件类
创建一个事件类,用于定义你想要在组件之间传递的事件。这个类可以是任何普通的Java类,但是通常建议使用一个简单的POJO类。例如,创建一个名为MessageEvent的事件类:
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
3.注册和取消注册事件
在组件中,你需要注册和取消注册事件。通常,在Activity的onCreate()方法中注册事件,在onDestroy()方法中取消注册。例如,在一个Activity中注册事件:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
4.发布事件
在发送事件的组件中,你可以使用EventBus的post()方法来发布事件。例如,在Activity中发布一个MessageEvent:
EventBus.getDefault().post(new MessageEvent("Hello, EventBus!"));
5.订阅事件
在接收事件的组件中,你需要创建一个订阅方法来处理接收到的事件。这个方法需要使用@Subscribe注解进行标记,并且需要一个参数来接收事件。例如,在Activity中订阅MessageEvent:
@Subscribe
public void onMessageEvent(MessageEvent event) {
String message = event.getMessage();
// 处理接收到的事件
Log.d(TAG, "onMessageEvent: " + message);
}
当有地方发布了时间之后,就会触发onMessageEvent。打印如下:
这就是使用Event Bus进行事件通信的基本步骤。
三、Event Bus的高级用法
1.粘性事件 (Sticky Event)
Event Bus还支持粘性事件,这意味着当一个事件被发布后,如果有订阅者注册了该事件,它将立即接收到该事件。干描述可能没什么实际场景,下面我讲一个例子:
假设你有一个应用程序,其中包含一个登录功能。当用户成功登录时,你可能希望在其他组件中知道用户已登录的状态。这时,你可以使用粘性事件。
首先,在登录成功的地方,你可以发布一个粘性事件,表示用户已登录:
EventBus.getDefault().postSticky(new LoginEvent(true));
然后,在其他组件中,你可以订阅这个粘性事件,以获取用户登录状态:
@Subscribe(sticky = true)
public void onLoginEvent(LoginEvent event) {
boolean isLoggedIn = event.isLoggedIn();
// 处理用户登录状态
}
即使在订阅方法注册之前,如果有一个粘性事件已经发布,订阅方法仍然会被立即调用,并且可以获取到最近一次的粘性事件。
这样,当用户登录成功后,其他组件可以立即获取到用户登录状态,而不需要依赖其他的传递机制。
2.优先级(Priority)
事件订阅方法可以通过设置优先级来定义它们的执行顺序。通过@Subscribe注解的priority参数,可以指定订阅方法的优先级。优先级值越高,订阅方法越早执行。
假设你有一个音频播放应用程序,其中包含一个音频播放器组件和一个通知组件。当音频播放器开始播放音频时,你希望通知组件立即显示一个通知,告知用户当前正在播放的音频。
首先,你可以定义一个播放事件和一个通知事件:
public class PlayEvent {
// 播放事件类
}
public class NotificationEvent {
// 通知事件类
}
然后,在音频播放器组件中,你可以发布一个播放事件:
EventBus.getDefault().post(new PlayEvent());
接下来,在通知组件中,你可以订阅通知事件,并设置一个较高的优先级,以确保它在其他事件处理之前被调用:
@Subscribe(priority = 1)
public void onNotificationEvent(NotificationEvent event) {
// 显示通知
}
在订阅方法上,通过设置priority属性为一个较高的值(例如1),你可以确保该方法在其他订阅方法之前被调用。
这样,当音频播放器发布播放事件时,通知组件的订阅方法会被优先调用,从而立即显示通知。优先级的使用场景还包括事件的拦截和处理顺序的控制。你可以定义多个订阅方法来处理相同类型的事件,通过设置不同的优先级来决定它们的执行顺序。
总结:通过设置订阅方法的优先级,你可以控制事件的处理顺序。在音频播放应用程序中,通过设置通知组件的订阅方法的优先级为较高值,可以确保它在其他事件处理之前被调用,从而实现立即显示通知的功能。
3.线程模式(ThreadMode)
除了在@Subscribe注解中指定线程模式外,还可以通过EventBus的setDefaultThreadMode()方法设置默认的线程模式。这样,在订阅方法上没有指定线程模式时,将使用默认的线程模式。
// 设置默认的线程模式
EventBus.getDefault().setDefaultThreadMode(ThreadMode.BACKGROUND);
// 订阅方法使用默认的线程模式
@Subscribe
public void onEvent(Event event) {
// 在后台线程中执行
// ...
}
// 订阅方法指定特定的线程模式
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(Event event) {
// 在主线程中执行
// ...
}
4.自定义事件类型
Event Bus允许使用任何类型的对象作为事件类型,不仅限于基本数据类型或特定的事件类。这样可以更灵活地定义和传递事件。
// 自定义事件类
public class CustomEvent {
// 自定义事件的属性和方法
// ...
}
// 发布自定义事件
EventBus.getDefault().post(new CustomEvent());
// 订阅自定义事件
@Subscribe
public void onCustomEvent(CustomEvent event) {
// 处理自定义事件
// ...
}
三、Event Bus和Handler的区别
Event Bus和Handler都可以用于实现事件的发布和订阅,但它们在实现方式和使用场景上有一些区别。
Event Bus是一种发布/订阅模式的实现,它允许不同组件之间通过事件进行解耦。Event Bus可以在同一个应用程序内的不同组件之间传递事件,也可以在不同应用程序之间传递事件(通过一些跨应用通信机制)。Event Bus提供了订阅和发布事件的简单API,并且支持一些高级功能,如粘性事件、优先级、取消订阅等。Event Bus可以处理多个订阅者同时接收事件的情况。
Handler是Android中的一个类,它用于在不同线程之间进行通信。Handler可以将消息或Runnable对象发送到目标线程的消息队列中,并在目标线程中处理这些消息或Runnable。Handler通常用于在后台线程中执行耗时操作,并将结果发送到主线程更新UI。Handler的主要目的是实现线程间的通信和任务调度。
虽然Event Bus和Handler都可以实现事件的发布和订阅,但它们的设计目的和使用场景略有不同。Event Bus更适合于解耦不同组件之间的事件传递,而Handler更适合于线程间的通信和任务调度。你可以根据具体的需求和场景选择使用Event Bus或Handler。