EventBus 使用详解

作者: 枫未晚 | 来源:发表于2022-05-08 10:36 被阅读0次

    传统的通信方式包括:Handler、BroadcastReceiver、Interface回调等,而 EventBus 简化了应用程序内各组件间、组件与后台线程间的通信。

    首先导入依赖

    // Android project
    implementation("org.greenrobot:eventbus:3.3.1")
    
    // Java project
    implementation("org.greenrobot:eventbus-java:3.3.1")
    

    基本使用

    使用如同发布订阅,先创建事件,也就是创建任意一个类,这个就是 Event 事件,再使用如下方法发布出去,此时订阅该事件的方法则会被调用

    EventBus.getDefault().post(TestEvent())
    

    订阅事件时,需要事先注册EventBus,一般在onStart方法中注册

    if (!EventBus.getDefault().isRegistered(this)) {
        EventBus.getDefault().register(this)
    }
    

    别忘了还要在onStop方法取消注册

    EventBus.getDefault().unregister(this)
    

    订阅事件,也就是写一个方法,参数是事先创好的类(即事件),然后用@Subscribe注解声明,当发布该事件时则调用这个方法,需要携带的数据也可以通过该类携带

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onTestEvent(event: TestEvent) {
        // 业务
    }
    

    四种线程模型
    EventBus3.0有四种线程模型,分别是:

    • POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
    • MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
    • BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
    • ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

    粘性事件

    事件通过post发送给EventBus后,当前已经订阅过的方法当然可以收到,但是如果发送的时候还未订阅,后续再订阅也收不到这个事件。例如,一个Activity要求它管理的所有Fragment都能执行某一个事件,但是当前我只初始化了3个Fragment,如果这时候通过post发送了事件,那么当前的3个Fragment当然能收到。但是这个时候又初始化了2个Fragment,那么我必须重新发送事件,这两个Fragment才能执行到订阅方法。

    粘性事件就是为了解决这个问题,通过 postSticky 发送粘性事件,这个事件不会只被消费一次就消失,而是一直存在系统中,直到被 removeStickyEvent 删除掉,那么只要订阅了该粘性事件即可收到并执行。

    # 发送粘性事件
    EventBus.getDefault().postSticky(TestEvent()) 
    
    # 移除粘性事件
    EventBus.getDefault().removeStickyEvent(TestEvent())
    

    接收粘性事件除了用@Subscribe注解声明,还需要添加 sticky = true 属性

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    fun onTestEvent(event: TestEvent) {
        // 业务
    }
    

    注意事项

    • Event 事件。它可以是任意类型。
    • Subscriber 事件订阅者。在EventBus3.0之前我们必须定义以onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync开头的方法,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe(),并且指定线程模型,默认是POSTING。
    • Publisher 事件的发布者。可以在任意线程里发布事件。

    使用场景

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

    2. activity和fragment交互或fragment之间进行通信,用广播和接口都比较麻烦。

    3. 交互流程跨多个界面,如发朋友圈,可以拍照或从相册选取照片,可能还需要剪切,但最终也只是需要照片地址,用EventBus传递数据则比较方便

    总结:主要是在常规通信方式写起来很复杂或需要解耦的情况下使用EventBus

    相关文章

      网友评论

        本文标题:EventBus 使用详解

        本文链接:https://www.haomeiwen.com/subject/crxzyrtx.html