EventBus

作者: 壹零二肆 | 来源:发表于2020-09-20 14:05 被阅读0次
  • 1 概述
  • 2 原理
  • 3 使用
  • 4 源码
  • 5 总结

https://greenrobot.org/eventbus/documentation/
https://github.com/greenrobot/EventBus

1 概述

EventBus Publisher 将 Event 交给 EventBus
EventBus 转交给 Subscriber
Subscriber 在其回调中消费处理 Event

提供能力:

  • ThreadMode
  • StickyEvent (ClassType <-> Event)
  • subscribe priority & Event Cancle

2 原理

  • register 将会在该类内部进行解析,带有 subscribe 注解的方法会被提取为观察者接受回调

  • post 发送 event

  • threadMode 处理线程切换,利用队列来保存Event 进行线程调度

  • StickyEvent @Subscribe(sticky = true) 则会在 subscriber register 时候将所有的 stickyEvent 回调所有 注解sticky = true 的 subscribe method

  • Priority: 解析 @Subscribe(priority = 1) 将在插入 subscription 的时候将该订阅 位置靠前 default priority = 0

  • Cancel 在 for 中会分发 Event 到 每个 Subscription Cancel --> break

  • index 索引 解析形成 SubscribeMethod 采用注解解析生成器做处理,不使用默认的反射提高效率

        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);

        ...

        if (ignoreGeneratedIndex) {
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
            subscriberMethods = findUsingInfo(subscriberClass);
        }

3 使用

官方教程
https://greenrobot.org/eventbus/documentation/how-to-get-started/

代码:


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MessageEvent(System.currentTimeMillis()+""));
            }
        });
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void homeText(MessageEvent event) {
        textView.setText(event.content);
    }

    @Override
    protected void onStart() {
        EventBus.getDefault().register(this);
        super.onStart();
    }

    @Override
    protected void onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop();
    }  

4 源码

  • EventBus
    • eventTypesCache
    • DEFAULT_BUILDER
    • defaultInstance
    • eventTypesCache
    • subscriptionsByEventType
    • typesBySubscriber
    • stickyEvents
    • mainThreadSupport
    • mainThreadPoster
    • backgroundPoster
    • asyncPoster
    • subscriberMethodFinder
    • executorService
  • Poster
    • enqueue
  • Subscription

    • subscriber
    • subscriberMethod
  • SubscriberMethod

    • method
    • threadMode
    • eventType
    • priority
    • sticky

5 总结

  • 注解
  • 观察者模式
  • 线程调度

后台线程 和 主线程 切换:

   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);
        }
    }

class AsyncPoster implements Runnable, Poster {

    private final PendingPostQueue queue;
    private final EventBus eventBus;

    AsyncPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        queue.enqueue(pendingPost);
        eventBus.getExecutorService().execute(this);
    }

    @Override
    public void run() {
        PendingPost pendingPost = queue.poll();
        if(pendingPost == null) {
            throw new IllegalStateException("No pending post available");
        }
        eventBus.invokeSubscriber(pendingPost);
    }

}

五种模式的特征各不相同

相关文章

网友评论

      本文标题:EventBus

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