EventBus 3.X使用
EventBus介绍
是一个Android和Java的开源库,使用发布者/订阅者模式进行松散耦合。 EventBus只需几行代码即可实现与分离类的集中通信 - 简化代码,消除依赖关系,并加速应用程序开发。Github地址
阿里巴巴Android开发手册也推荐使用EventBus传递数据
使用场景:
- 替代接口回调传递数据
- Intent专递数据等
- 各种数据传递场景
使用
- 引用
implementation 'org.greenrobot:eventbus:3.1.1'
- 定义待发送实体类,类型可以是任意java bean
public class MessageEvent {
public final String username;
public final int age;
public MessageEvent(String username, int age) {
this.username = username;
this.age = age;
}
}
- 注册订阅者(也就是接收者),并在其生命周期绑定和解绑订阅者,大部分场景(activity和fragment)可以在onstart和onstop进行操作,其中的threadMode指定订阅的方法体运行在那种线程中,运行的方式包括:POSTING,MAIN,MAIN_ORDERED,BACKGROUND,ASYNC。具体区别在本文末尾介绍
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
Log.i("test", event.username + event.age);
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
- 发布订阅消息
EventBus.getDefault().post(new MessageEvent("张三", 34));
关于订阅者无法收到消息的问题:
按照以上流程使用,然后在项目中使用,从activity A跳转到activity B,并发送了一个消息给activity B,发现activity B注册的订阅者无法收到消息,what the fu*k,你在逗我,根本用不了。
- 原因:Eventbus普通的订阅事件,即eventbus.getDefault().post(xxx)方法必须是在订阅后发送消息才可接收到,从A启动B,此时A已发送,B还未注册,所以B无法收到A的事件。
- 解决办法:使用EventBus粘性事件,用它可以实现订阅在消息发送后注册接收收到消息
EventBus.getDefault().postSticky(new MessageEvent("张三", 34));
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onMessage(MessageEvent event) {
Log.i("test", event.username + event.age);
}
五种ThreadMode区别
-
ThreadMode.POSTING
订阅者将在发布事件的同一线程中调用。这是默认值。事件传递是同步完成的,一旦发布完成,所有订阅者都将被调用。此ThreadMode意味着开销最小,因为它完全避免了线程切换。因此,这是已知完成的简单任务的推荐模式,是一个非常短的时间而不需要主线程。使用此模式的事件处理程序应该快速返回以避免阻止发布线程(在主线程时)。 -
ThreadMode.MAIN
订阅者将在Android的主线程(有时称为UI线程)中调用。如果发布线程是主线程,则将直接调用事件处理程序方法(与ThreadMode.POSTING所描述的同步)。使用此模式的事件处理程序必须快速返回以避免阻塞主线程。 -
ThreadMode: MAIN_ORDERED
订阅者将在Android的主线程中调用。该事件总是排队等待以后交付给订阅者,因此对post的调用将立即返回。这为事件处理提供了更严格且更一致的顺序(因此名称为MAIN_ORDERED)。例如,如果您在具有MAIN线程模式的事件处理程序中发布另一个事件,则第二个事件处理程序将在第一个事件处理程序之前完成(因为它是同步调用的 - 将其与方法调用进行比较)。使用MAIN_ORDERED,第一个事件处理程序将完成,然后第二个事件处理程序将在稍后的时间点调用(一旦主线程具有容量)。使用此模式的事件处理程序必须快速返回以避免阻塞主线程 -
ThreadMode:ASYNC
事件处理程序方法在单独的线程中调用。这始终独立于发布线程和主线程。发布事件永远不会等待使用此模式的事件处理程序方法。如果执行可能需要一些时间,例如事件处理程序方法应使用此模式。用于网络访问。避免同时触发大量长时间运行的异步处理程序方法来限制并发线程数。 EventBus使用线程池从已完成的异步事件处理程序通知中有效地重用线程。 -
ThreadMode:BACKGROUND
订阅者将在后台线程中调用。如果发布线程不是主线程,则将在发布线程中直接调用事件处理程序方法。如果发布线程是主线程,则EventBus使用单个后台线程,该线程将按顺序传递其所有事件。使用此模式的事件处理程序应尝试快速返回以避免阻塞后台线程。
暂时这么多后续遇到问题再更新,欢迎指正