美文网首页
EventBus3.0源码分析

EventBus3.0源码分析

作者: 心无止境_GX | 来源:发表于2020-03-16 15:21 被阅读0次

    基本使用方式:

    1、build中依赖,直接使用
    implementation 'org.greenrobot:eventbus:3.0.0'

    2、在需要接收事件的Fragment或者Activity或者View中注册,并且加入订阅方法,在onDestroy中进行解除注册

    EventBus.getDefault().register(this);

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageString(String s) {
    //接收到事件
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
    }

    3、发送事件
    EventBus.getDefault().post("post message");

    上面是基本的用法,EventBus有两个要素,发送、订阅,先说订阅,因为你不订阅,事件发送出去也没地方接收

    前言
    我们先明确两件事件(我自己的归类):
    订阅包含(注册、订阅、解除注册)
    发送包含(发送普通事件,发送粘性事件,取消事件)

    订阅

    1、注册
    EventBus有两种方式获取实例:
    第一种通过EventBusBuilder的build去注册,这种方式可以自己去配置一些自己想要的属性
    EventBusBuilder builder = EventBus.builder();
    builder.build().register(this);

    image.pngimage.png

    第二种直接采用默认配置
    EventBus.getDefault().register(this);

    register方法中,通过调用subscriberMethodFinder的findSubscriberMethods(subscriberClass)方法去查询出该订阅对象中所有的订阅方法(订阅方法就是带有@Subscribe注解的),并且将所有的订阅方法注册到EventBus中

    image.pngimage.png

    2、订阅(Subscribe)
    在注册的时候提到了一点,findSubscriberMethods(subscriberClass)方法会查询出所有的订阅方法,并注册到EventBus中去,这里的订阅要满足四个条件,Subscribe注解、public修饰、void返回、单参数

    image.pngimage.png

    上面是Subscribe的注解类,我们可以看到里面有三个参数
    2.1、threadMode:总共有五种mode

    • POSTING(默认):和发送事件处在同一线程中,因为他和发送事件处在同一线程,避免了线程切换,所以是开销最小的。使用此模式不要在主线程中发送事件,避免线程阻塞
    • MAIN:处于主线程中接收事件,别处理耗时操作,会阻塞
    • MAIN_ORDERED:处于主线程中接收事件,与MAIN不同,事件接收将始终等待传递(这是后期才出的模式)
    • BACKGROUND:如果发送事件在主线程,接收事件方法在后台调用,后台线程将依次交付事件;如果发送事件不是在主线程,则接收事件处于和发送事件同一个线程
    • ASYNC:接收事件处于一个独立的线程,EventBus使用线程池,重复利用已完成了异步订阅的线程

    2.2、sticky:是否发送粘性事件,默认为false,粘性事件就是先发送,等到订阅者订阅后再接收事件
    场景:请求到了数据,但是界面还没有完全初始化完成,那个时候还没有订阅者出现,这时候就需要用到粘性事件,先将事件发出去,等到订阅者出现后,再接收数据。

    为了节省开销(postSticky的时候会将事件存进对象中去,不销毁会占着内存位置),发送粘性事件的时候记得一定要在订阅方法结束时使用removeStickyEvent回收掉这个粘性事件

    2.3、priority:设置优先级的,相同的Mode下,优先级高的会比优先级低的更先接收到事件,默认为0

    3、解除注册
    ** **解除注册的时候将从该订阅者中取出所有的订阅方法get(subscriber),然后从该订阅者中解除订阅(unsubscribeByEventType(subscriber, eventType)),全部订阅方法都解除了后,将该订阅者从EventBus中移除(remove(subscriber))

    image.pngimage.png

    发送

    1、发送普通事件
    使用EventBus.getDefault().post("post message");来发送普通事件,
    2、发送粘性事件
    使用EventBus.getDefault().postSticky("post message");来发送粘性事件,粘性事件在订阅部分中提过了


    image.pngimage.png

    粘性事件也是走post方法,post方法中会去遍历队列,执行postFin gleEvent方法,并且遍历一次就将队首remove掉,直到队列为空


    image.pngimage.png
    postSingleEvent:根据event(这个就是订阅方法中的那个接收的参数)去查询出所有的订阅方法,然后调用每个订阅方法

    这里建议每个订阅方法的参数都是一个实体类,别用通用类型的参数,比如String这种,不然发送的时候会给一些不需要的订阅方法传递参数

    image.pngimage.png image.pngimage.png

    根据不同的线程模式,去调用相应的方法


    image.pngimage.png

    EventBus的发送、接收流程大致就是这样

    收!

    参考链接:
    感谢!感谢!感谢!
    https://www.jianshu.com/p/1eaca34e5314
    https://www.jianshu.com/p/92a4b2a5abc6

    相关文章

      网友评论

          本文标题:EventBus3.0源码分析

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