美文网首页
EventBus实现原理

EventBus实现原理

作者: 碎念枫子 | 来源:发表于2023-04-03 16:28 被阅读0次

    今天就来重新的复习一下EventBus的实现原理

    EventBus是一个 Android开发中常用的事件发布/订阅库,它通过解耦不同组件之间的交互,使得代码更加简洁易读。

    优点:框架本身简单、简洁。

    使用方法

    EventBus是一个单例,订阅者通过他的EventBus.getDefault().register(this),来注册,通过EventBus.getDefault().unregister(this)来解除绑定,这通常在activity或者fragment的生命周期中调用。

    @Override
     public void onStart() {
         super.onStart();
         EventBus.getDefault().register(this);
     }
    
     @Override
     public void onStop() {
         super.onStop();
         EventBus.getDefault().unregister(this);
     }
    

    在其他代码组件发送消息:

    EventBus.getDefault().post(new MessageEvent());
    

    订阅者接收到消息,对应MessageEvent参数的订阅方法就会被调用,方法可以定义被调用的执行线程

    //ThreadMode.POSTING,默认的线程模式,在那个线程发送事件就在对应线程处理事件,避免了线程切换,效率高。
    //ThreadMode.MAIN,如在主线程(UI线程)发送事件,则直接在主线程处理事件;如果在子线程发送事件,则先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
    //ThreadMode.MAIN_ORDERED,无论在那个线程发送事件,都先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
    //ThreadMode.BACKGROUND,如果在主线程发送事件,则先将事件入队列,然后通过线程池依次处理事件;如果在子线程发送事件,则直接在发送事件的线程处理事件。
    //ThreadMode.ASYNC,无论在那个线程发送事件,都将事件入队列,然后通过线程池处理。
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event){
        Log.d("execute",event.toString());
    }
    

    原理

    注册与反注册

    订阅者在注册时后,通过反射原理找出订阅者所有含subscribe注解修辞的方法,并且保存在一个HashMap中(typesBySubscriber),这个HashMap以注册对象为keySubscriberMethodvalue。同时也会保存一个以EventTypekeySubscription对象集合为value的的HashMapsubscriptionsByEventType),然后对粘性事件做特殊处理,粘性事件将会放到一个HashMap中(stickyEvents),这个HashMapEventTypekeyEvent对象value,会一直存在内存中,需要人为维护。

    同样的,反注册主要也是以删除typesBySubscribersubscriptionsByEventType 这两个HashMap中的关联对象操作处理的

    发送消息

    将消息保存在列队中,然后交给正在处于posting的方法执行线程循环出列, 并且调用postSingleEvent(),这里根据情况找出消息的所有父类,并且执行postSingleEventForEventType(),这里会在subscriptionsByEventType找出所有的订阅者,调用postToSubscription(),这里会调用不同的ThreadMode进行不同的线程调度或者执行。

    线程调度

    线程调度主要是通过Handler实现的,发送消息时最终会调用到HandlerPoster的enqueue()方法。

    HandlerPoster的enqueue()方法主要就是将subscriptionevent对象封装成一个PendingPost对象,然后保存到队列里,之后通过Handler切换到主线程,在handleMessage()方法将中将PendingPost对象循环出队列,交给invokeSubscriber()方法做进一步处理。

    粘性事件

    在注册订阅者的时候,会去stickEvent中取出所有粘性事件处理。

    相关文章

      网友评论

          本文标题:EventBus实现原理

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