EventBus使用总结和使用场景

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/f552126367/article/details/86571012

一、EventBus介绍

EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。传统的事件传递方式包括:Handler、BroadcastReceiver、Interface回调,相比之下EventBus的优点是代码简洁,使用简单,并将事件发布和 订阅充分解耦。

二、使用场景

刚开始接触EventBus的使用,感觉EventBus既然这么强大,可以快捷方便的进行各组件之间的消息传递,那是不是就完全可以取代Intent、BroadcastReceiver、Handler等方式了。后来查了许多资料发现其实不是的,它也有很多限制。

1、Event会根据传递的参数给所有接收者都传递消息,这就导致如果你想给指定一个类里发布消息就得自己写一个接口类,要不然就会好多执行者都会执行该方法,所以一般能用Intent组件传值时还是用Intent。

2、EventBus相对于BroadCast,广播是相对消耗时间、空间最多的一种方式,但是大家都知道,广播是四大组件之一,许多系统级的事件都是通过广播来通知的,比如说网络的变化、电量的变化,短信发送和接收的状态,所以,如果与android系统进行相关的通知,还是要选择本地广播;在BroadcastReceiver的 onReceive方法中,可以获得Context 、intent参数,这两个参数可以调用许多的sdk中的方法,而eventbus获得这两个参数相对比较困难。

3、EventBus相对于handler,可以实现handler的方式,但是也会面对有许多接收者的问题,所以如果是线程回调的话,我觉得还是用handler比较好。

4、使用场景总结:所以EventBus最好的使用方式就是替代某些BroadcastReceiver和Interface;如fragment之间进行通信,用广播和接口都比较麻烦,而用EventBus则比较简单。

三、具体使用方法

1、EventBus的四种线程模型(ThreadMode)

POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起应用程序无响应(ANR)。
MAIN:事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。

2、基本使用

自定义一个事件类

public class AnyEventType {
     public AnyEventType(){}
 }

在要接受消息的页面注册

EventBus.getDefault().register(this);

接收消息的方法

@Subscribe
public void onEvent(AnyEventType event) {/* Do something */};

发送消息

EventBus.getDefault().post(event);

取消注册

EventBus.getDefault().unregister(this);

传递的值可自定义class,也可传递字符串,EventBus会根据传递的类型判断都有哪些接收者接收,如果有多个方法,则传递给所有接收者。

3、粘性事件 

    之前说的使用方法,都是需要先注册(register),再post,才能接受到事件;如果你使用postSticky发送事件,那么可以不需要先注册,也能接受到事件,也就是一个延迟注册的过程。 
   普通的事件我们通过post发送给EventBus,发送过后之后当前已经订阅过的方法可以收到。但是如果有些事件需要所有订阅了该事件的方法都能执行呢?例如一个Activity,要求它管理的所有Fragment都能执行某一个事件,但是当前我只初始化了3个Fragment,如果这时候通过post发送了事件,那么当前的3个Fragment当然能收到。但是这个时候又初始化了2个Fragment,那么我必须重新发送事件,这两个Fragment才能执行到订阅方法。 
   粘性事件就是为了解决这个问题,通过 postSticky 发送粘性事件,这个事件不会只被消费一次就消失,而是一直存在系统中,知道被 removeStickyEvent 删除掉。那么只要订阅了该粘性事件的所有方法,只要被register 的时候,就会被检测到,并且执行。订阅的方法需要添加 sticky = true 属性。

构造发送信息类:

public class StickyEvent {
    public String msg;

    public StickyEvent(String msg) {
        this.msg = msg;
    }
}

发布消息:EventBus.getDefault().postSticky(new StickyEvent(“我是粘性事件”));
接收消息:和之前的方法一样,只是多了一个 sticky = true 的属性。

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onEvent(StickyEvent event){
    tv_c_result.setText(event.msg);
}
1
2
3
4
注册:

EventBus.getDefault().register(CActivity.this);
1
解注册:

EventBus.getDefault().removeAllStickyEvents();
EventBus.getDefault().unregister(CActivity.class);
 

猜你喜欢

转载自blog.csdn.net/f552126367/article/details/86571012