美文网首页
EventBus流程和工作原理

EventBus流程和工作原理

作者: Joe_2e0c | 来源:发表于2019-05-27 10:24 被阅读0次

1,注册订阅者

     EventBus 的创建 getDefault() 是一个双重校验锁的单例模式。建造者模式Builder,观察者模式。

2,事件发布

3,反注册订阅者

1. 注册EventBus,EventBus会获取当前类中的订阅方法,包括方法的参数,类型,优先级等信息。在获取的方法中,会先遍历缓存。如果在缓存中没有才去调用获取方法。

2. 获取订阅方法有两种方式,一种是反射,反射获取全部方法,找到加了@Subscribe注解并有一个参数的方法,另外一种是通过订阅方法索引来得到订阅方法。反射的效率较低,所以优先使用用订阅方法索引来获取,当索引列表找不到这个方法。它就会走反射的途径。注册过后这个订阅方法就被存起来了。等待接受消息。

findSubscriberMethods找出一个SubscriberMethod的集合

3. 在3.0以前是没有注解方法的那时候都是通过反射来获取和执行方法。而且方法必须以onEvent开头,分别为onEventMainThead,onEventBackground,onEvent,onEventAsync,3.0以后就全部替换为注解的形式

4. postEvent,会把这个Event加入消息队列,然后通过Event的类型信息来得到它的订阅方法,然后根据相应的订阅方式反射调用订阅方法。没有选择的threadMode的post一般都会在UI线程执行。如果当前post不是UI线程,这边会用Handle的机制来让接受Event的方法运行在UI线程。

5. 解除注册,将该对象从对象缓存列表中移除,获取当前对象的订阅列表,然后将其从订阅列表移除

---------------------

总结一下EventBus的工作原理

6.1 订阅逻辑

1、首先用register()方法注册一个订阅者

2、获取该订阅者的所有订阅的方法

3、根据该订阅者的所有订阅的事件类型,将订阅者存入到每个以 事件类型为key 以所有订阅者为values的map集合中

4、然后将订阅事件添加到以订阅者为key 以订阅者所有订阅事件为values的map集合中

5、如果是订阅了粘滞事件的订阅者,从粘滞事件缓存区获取之前发送过的粘滞事件,响应这些粘滞事件。

6.2 事件发送逻辑

1、首先获取当前线程的事件队列

2、将要发送的事件添加到事件队列中

3、根据发送事件类型获取所有的订阅者

4、根据响应方法的执行模式,在相应线程通过反射执行订阅者的订阅方法

6.3 取消逻辑

1、首先通过unregister方法拿到要取消的订阅者

2、得到该订阅者的所有订阅事件类型

3、遍历事件类型,根据每个事件类型获取到所有的订阅者集合,并从集合中删除该订阅者

4、将订阅者从步骤2的集合中移除

6.4 利与弊

EventBus好处比较明显,它能够解耦和,将业务和视图分离,代码实现比较容易。而且3.0后,我们可以通过apt预编译找到订阅者,避免了运行期间的反射处理解析,大大提高了效率。当然EventBus也会带来一些隐患和弊端,如果滥用的话会导致逻辑的分散并造成维护起来的困难。另外大量采用EventBus代码的可读性也会变差。

图是EventBus整体的运行图。事件的发布与事件的消费可能位于一个线程,也可能位于不同的线程。这取决于我们注册消费方法的时候设置的ThreadMode。

每一个线程都有一个与之关联的Queue(通过ThreadLocal办到的),事件被发布到Queue中,循环遍历Queue中的Event,并根据Event查找可以消费该事件的类(MainActivity)与方法(@Subscribe)。最终将事件交给消费方法完成一次完整的发布与消费过程。

---------------------

EventBus支持的四种线程模式(ThreadMode):

      示例:

@Subscribe(threadMode = ThreadMode.POSTING)

    public void eventBus(MyEvent myEvent) {

        Toast.makeText(this, "呵呵哒", Toast.LENGTH_SHORT).show();

    }

      a)POSTING(默认):事件在哪个线程发布,就在哪个线程消费,因此要特别注意不要在UI线程进行耗时的操作,否则会ANR;

      b)MAIN:事件的消费会在UI线程。因此,不宜进行耗时操作,以免引起ANR。

      c)BACKGROUND:如果事件在UI线程产生,那么事件的消费会在单独的子线程中进行。否则,在同一个线程中消费。

      d)ASYNC:不管是否在UI线程产生事件,都会在单独的子线程中消费事件。

另外,EventBus还支持粘性事件,即发送一个未注册的粘性事件,注册者会在完成注册之后收到这个粘性事件。

相关文章

  • EventBus流程和工作原理

    1,注册订阅者 EventBus 的创建getDefault()是一个双重校验锁的单例模式。建造者模式Buil...

  • EventBus工作原理

    以下总结转自:EventBus源码研读 EventBus工作原理 最后我们再来从设计者的角度看一看EventBus...

  • EventBus工作原理

    EventBus大家一定不陌生,组件之间传递消息只要post一下,对方就能收到,还可以任意切换线程,究竟内部是如何...

  • EventBus源码二:Post流程

    上篇文章介绍了EventBus注册流程, 本篇文章简介EventBus发送事件的流程 EventBus源码(一)[...

  • jvm工作原理详解

    参考:1 JVM 工作原理和流程

  • EventBus3.0源码分析(上)

    概述 关于EventBus3.x的用法,本文不再赘述,只分析其实现原理,官方的流程图: 订阅流程 需要订阅事件的对...

  • 第三方开源库源码のEventBus解析

    EventBus的使用 注册 定义subscriber 发送消息 发送黏性消息 流程图解 EventBus的流程 ...

  • 2019-06-19-满兜理财

    1.view绘制流程 2.okhttp,eventbus,retrofit原理 3.卡顿如何分析 4.如果刚接手一...

  • JVM工作原理和流程

    JVM的体系结构 Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Jav...

  • EventBus源码解析(三)—进阶源码

    1.EventBus源码解析(一)—订阅过程2.EventBus源码解析(二)—发布事件和注销流程3.EventB...

网友评论

      本文标题:EventBus流程和工作原理

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