EventBus源码解析

230 阅读1分钟

要探究的几个问题

  • 流程原理
  • 发送的消息,如何做到线程切换
  • 何为粘性事件,实现原理
  • EventBus使用缺点

流程

1.通过register来注册方法

通过ConcurrentHashMap来存储方法,key为注册类,value为注册类中的方法

  • 标注1为查找通过@Subscribe注解标注的方法
  • 标注2将查找的方法缓存起来

2.post发送事件

在EventBus类中

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch (subscription.subscriberMethod.threadMode) {
            case POSTING:
                invokeSubscriber(subscription, event);
                break;
            case MAIN:
                if (isMainThread) {
                    invokeSubscriber(subscription, event);
                } else {
                    mainThreadPoster.enqueue(subscription, event);
                }
                break;
            case MAIN_ORDERED:
                if (mainThreadPoster != null) {
                    mainThreadPoster.enqueue(subscription, event);
                } else {
                    // temporary: technically not correct as poster not decoupled from subscriber
                    invokeSubscriber(subscription, event);
                }
                break;
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
            case ASYNC:
                asyncPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }
    }

实现线程切换

这一步是真正的方法调用,通过反射

3.何为粘性事件

普通事件是必须先注册,才能发送成功,而粘性事件是将事件通过ConcurrentHashMap缓存起来,然后通过再发送

    public void postSticky(Object event) {
        synchronized (stickyEvents) {
            stickyEvents.put(event.getClass(), event);
        }
        // Should be posted after it is putted, in case the subscriber wants to remove immediately
        post(event);
    }

其中stickyEvents就是ConcurrentHashMap

不足之处

尽管EventBus简单解耦,但大量使用会造成程序的混乱