【Android】EventBus的使用

文章目录

    • 引入
      • EventBus三要素:
    • 使用
    • Subscribe注解介绍
      • 线程模型
      • sticky
      • priority
      • 异常处理

引入

EventBus是一个用于简化组件间通信的开源库,它使用发布-订阅模式(Pub-Sub)来实现事件的传递。

在Android开发中,不同的组件(例如Activity、Fragment、Service等)之间可能需要进行通信,例如一个组件发送一个事件,而其他组件可以订阅并接收该事件。这种通信方式可以帮助组件之间解耦,使代码更加清晰和可维护。

EventBus是一款针对Android优化的发布-订阅事件总线。其优点开销小,代码更优雅。

如果在FragmentFragment的交互,使用广播来处理,代码量大,并且效率不高,而且传递的数据是实体Bean类的话,需要序列化,那么成本就会变得很高。

使用EventBus可以实现以下功能:

  • 简化代码:通过使用EventBus,我们可以避免手动编写繁琐的接口回调或广播接收器等代码,简化了组件之间的通信逻辑。
  • 解耦组件:组件之间不需要直接引用彼此,而是通过事件进行通信,减少了组件之间的依赖性,提高了代码的可复用性和可测试性。
  • 线程管理:EventBus提供了线程模型,可以指定事件的发布和订阅在主线程或后台线程中执行,方便管理和控制线程。

EventBus三要素:

  • 事件(Event): 事件是在组件之间传递的数据载体。它可以是一个任意对象,包含需要传递的数据和方法。事件类通常包含一些字段和对应的getter方法,用来获取事件的数据。
public class MessageEvent {
    private String message;

    public MessageEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
  • 事件订阅者(Subscriber): 订阅者是对事件感兴趣并能够处理事件的组件。一个订阅者可以订阅多个事件,通过在方法上添加@Subscribe注解来标识订阅的方法(3.0之后),并且满足:

方法必须是公共的(public)。

方法只能有一个参数,参数类型是订阅的事件类

方法可以有任意的返回类型。

 	@Subscribe
    public void onMessageEvent(MessageEvent event) {
        String message = event.getMessage();
        // 处理接收到的事件
    }
  • 事件发布者(Publisher): 发布者是负责发布事件的组件。在需要发布事件的地方,通过调用EventBus的post()方法来发布事件。
EventBus.getDefault().post(new MessageEvent("Hello EventBus!"));

发布事件后,EventBus会将事件发送给所有订阅了该事件的订阅者,订阅者会根据事件的类型和参数来执行相应的方法来处理事件。

使用

当使用EventBus进行组件间通信时,可以采取以下详细步骤:

  • 添加EventBus依赖:在项目的build.gradle文件中添加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;
    }
}
  • 注册和取消注册:在接收事件的组件中,需要在合适的生命周期方法中注册和取消注册EventBus。//有点像广播
@Override
protected void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
protected void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}
  • 订阅事件:在接收事件的组件中,创建一个方法,并使用@Subscribe注解标记该方法,指定接收的事件类型。
@Subscribe
public void onMessageEvent(MessageEvent event) {
    String message = event.getMessage();
    // 处理接收到的事件
}

需要注意的是,订阅事件的方法名可以自定义,但需要保证方法是公共的(public),且只有一个参数。

  • 发布事件:在发送事件的组件中,使用EventBus的post()方法发布事件。
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注解介绍

Subscribe有三个参数(可选):threadModeboolean stickyint 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

黏性(sticky)事件是一种特殊类型的事件,它在事件发布后会一直保存在EventBus的内存中,直到被消费或手动删除。默认为false

使用黏性事件可以实现以下功能:

  1. 事件补发:当一个订阅者注册时,如果黏性事件存在,它会在订阅者注册后立即收到该事件。这样可以确保订阅者获取到最新的事件,而不需要等待下一次事件发布。
  2. 持久化状态:黏性事件可以持久化保存某个状态或数据。当订阅者注册时,它可以立即获取到该状态或数据,无需重新计算或请求。

订阅者方法会在订阅者注册后立即执行,并接收到最新的黏性事件。如果订阅者注册时,黏性事件已经存在,那么订阅者方法会立即执行并接收到该事件。

需要注意的是,使用黏性事件时要谨慎处理内存管理问题,避免事件过多导致内存泄漏或占用过多内存的情况。在不再需要黏性事件时,可以使用removeStickyEvent方法手动删除。

priority

EventBus的@Subscribe注解可以使用priority属性来设置订阅者方法的优先级。优先级决定了订阅者方法在事件发布时的执行顺序。

优先级是一个整数值,数值越小,优先级越高。默认情况下,优先级为0,所有订阅者方法的优先级相同。当设置priority属性时,数值越小,优先级越高。

如果优先级相同的订阅者方法存在,EventBus会根据注册的顺序来确定执行顺序。先注册的订阅者方法会先执行。

异常处理

为了确保代码的健壮性,可以在订阅方法上添加异常处理注解(@Subscribe,throwable = true),以捕获并处理订阅方法执行过程中可能发生的异常。

@Subscribe(throwable = true)
public void onMessageEvent(MessageEvent event) {
    // 处理事件,捕获可能发生的异常
}

你可能感兴趣的:(第三方开源库,android,java,androidx)