EventBus 源码分析(一)-----简单使用

EventBus 是在Android 中数据总线的框架,他基于观察者模式。他的优点是体积小,使用简单,效率高,支持不同的线程
如果你的项目中,经常需要在各个对象中传递数据,那么EventBus 将会是你不错的选择。
Git地址:https://github.com/greenrobot/EventBus

为什么我们要使用EventBus?

1、本身整个框架设计就是为了解决Android 广播那类型复杂的事件传递,这个思路也是EventBus 经久不衰发展并到3.0 的主要原因。
2、使用方便,注册、反注册、定义方法、发送就基本完成了整个逻辑流程
3、支持丰富,threadMode priority sticky 三个参数就能涵盖了所有使用场景。甚至register 并没有强制要求在activity 这类android context 中进行。
4、轻量,虽说现在手机容量逐步提升,但是轻量还是开发者考虑的一个重点方向。
 

一,使用
我们来看看EventBus 如何使用。我们先建立功能设计,目标是MainActivity 打开ButtonActivity ,ButtonActivity 中有个按钮,点击后向MainActivity 传递一段message

  1. 搭建项目
    你需要在你的app库的guild.gradle中dependencies节点下加入
    implementation 'org.greenrobot:eventbus:3.2.0'
  2. 需要创建一个对象,因为EventBus 的数据总线传输是基于对象的。
    public class SampleEvent{
        public String message;
        public SampleEvent(String message) {
            this.message = message;
        }
    }

    其中message 是等会用来传递数据的。实际使用中,如果没有数据传输过程,而只是一个事件传输,可以不带参数。

  3. 注册一个监听者
    在需要收到消息的对象中加入监听方法在这里我们是MainActivity,Activity/Fragment 一般写在OnCreate 方法中,你也可以写在希望开始监听的时刻。

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

    注意:如果重复注册了一个对象,则EventBus 会如下报错

    org.greenrobot.eventbus.EventBusException: Subscriber class MainActivity already registered to event class SampleEvent

    为了避免重复注册,可以在注册以前加入isRegistered 去判断是否注册过EventBus

  4. 在MainActivity对象退出或者决定不想监听事件时,加入以下代码

    if(EventBus.getDefault().isRegistered(this)){
        EventBus.getDefault().unregister(this);
    }

    这里实际上不加入注册判断也没有关系的,如果没有register 的对象去unregister,不会报错,只是log 里面会打印一段警告信息如下

    Subscriber to unregister was not registered before: class MainActivity
  5. 注册监听对象
    我们刚刚创建了一个SampleEvent对象,这个代表一个事件,其中message 是参数。
    我们需要在需要监听的对象(MainActivity) 中注册被回调的方法
    代码如下

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getEvent(SampleEvent event){
    }

    其中,Subscribe 的注解中,可以填入的参数有threadMode,sticky,priority这些参数。具体参数后面再去详细拓展

  6. 发送消息,在要发送信息的地方,如下调用就可以了​​​​​

    EventBus.getDefault().post(new SampleEvent("Send with ButtonActivity"));

 

到这里为止,最简单的EventBus 用法已经完成了

当运行时,调用第六步的时候,你会发现在MainActivity 中的getEvent 方法会收到SampleEvent 

二,额外参数

       EventBus 给我们带来的不单只是数据传输的便利性,他在额外参数,不多但足以让你应对各种情况。

  • ThreadMode --- 当你希望你注册的监听事件(方法)能在不同的情况下运行时,需要用到此参数,默认POSTING
     
POSTING这个模式下,可以理解为,表示执行事件方法的线程和发布事件处于同一个线程下
MAIN表示执行事件的线程方法总是在主线程内执行
MAIN_ORDERED这个模式下,需要等待上一个使用MAIN_PRDERED 的事件被执行完毕以后,此事件才会继续执行
BACKGROUND表示这个事件会在后台 运行
ASYNC

异步线程,表示这个事件独立于主线程和发布者线程执行,EventBus 会有一个线程池去管理这个事件










 

  • Sticky---粘性事件,接收事件的对象有可能没有register 则可以使用此方法,默认是false 
    接收true 和 false 作为参数值
  • priority --- 表示事件接收顺序,默认为0.
    EventBus 会根据这个数值的大小去判断执行顺序,数值越大,越先被执行,如果两个数值相同,越先被注册的越先被执行。

三,粘性事件

如果post Event 的时候监听的事件没有被注册,那么这个事件将不会被响应。
于是乎出现Stick粘性事件来解决这个问题。

 1. 注册粘性接收事件

@Subscribe(threadMode = ThreadMode.MAIN , sticky = true)
public void getEvent(SampleEvent event){
....
EventBus.getDefault().removeSticky(event)
}

 2. 发送粘性事件

EventBus.getDefault().postSticky(new SampleEvent());

3.    开启接收
将接收事件的class 进行注册

EventBus.getDefault().register(this)

此时,步骤1 的方法就会被调用

4.接收完以后,我们需要主动调用去删除粘性事件

EventBus.getDefault().removeSticky(event)

四、 使用EventBus 注意的地方

        1、register 一定需要在不需要监听或者activity 推出以后进行unregister ,否则会导致内存溢出。
        2、sticky 事件:如果你的sticky 事件接收的时候需要修改UI 之类的动作,注意你的register 动作需要在UI 准备好的时候,否则可能导致nullPointException
        3、sticky 事件:使用完毕以后注意remove ,另外也有可能你调用了postSticky 以后,没有注册sticky事件的方法接收了,然后remove 会导致后续需要接收sticky 方法的地方没有收到事件。总之,使用sticky 事件一定要管理好什么时候remove ,什么时候发送的逻辑
        4、除非你很清楚你需要什么,否则永远不要将EventBus 的注册写在activity基类,因为不是所有页面都需要用到EventBus,但是注册内部使用的是反射,势必会造成效率低下,甚至有可能因为没有正确unRegister导致内存溢出 

下篇,源码分享
https://blog.csdn.net/wzhseu/article/details/81433936

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值