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