zoukankan      html  css  js  c++  java
  • 仿EventBus做一个简单的基于订阅发布的事件总线

    一、概述

      在上一节分析了EventBus的源代码。本节仿照EventBus自己做一个事件总线框架,去掉了一些代码,只保留了核心框架,旨在梳理框架的框架原理,加深对框架流程的理解。

      在贴出源代码之前先把这个自定义的EventBus的功能介绍一下。核心流程还是三个,注册、发布、取消注册(未写AnnotationProcessor部分,如果有需要大家可以自己实现),源码中的类绝大部分分仿照了EventBus原有的类名,只是类里面的内容做了简化调整。如:EventBus类只抽离了、post、register、unregister、subscribe方法等。

      完整源代码下载地址

      下面贴出library结构

      

     自己实现的框架其用法和EventBus还是一样的,只是不能发送黏性事假和定义事件的优先级,使用实例代码如下:

    public class MainActivity extends AppCompatActivity {
        private Button btn;
        private TextView tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            /**
             * 注册观察者对象
             */
            EventBus.getDefault().register(this);
            btn = findViewById(R.id.main_btn);
            tv = findViewById(R.id.main_tv);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    toPost();
                }
            });
    
        }
    
        /**
         * 用于接收post发送过来的事件
         *
         * @param event 具体的事件主体
         */
        @Subscribe
        public void onMessageEvent(MessageEvent event) {
            switch (event.getArg1()) {
                case 0:
                    tv.setText("接收小消息为:" + event.getMsg());
                    break;
    
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            /**
             * 取消订阅
             */
            EventBus.getDefault().unRegister(this);
        }
    
        /**
         * 发送消息
         */
        public void toPost() {
            MessageEvent event = new MessageEvent();
            event.setArg1(0);
            event.setMsg("杨洛峋小宝宝来了");
            EventBus.getDefault().post(event);
        }
    
    }
    

     

    二、源码介绍以及源码截图

      下面提出关键源代码

      EventBus.getDefault().register(subscriber)

      /**
         * 注册
         * 订阅方法
         *
         * @param subscriber
         */
        public void register(Object subscriber) {
            Class clazz = subscriber.getClass();
            List<SubscriberMethod> subscriberMethods = SubscriberMethodFinder.findSubscriberMethods(clazz);
            if (subscriberMethods != null && subscriberMethods.size() > 0) {
                for (SubscriberMethod subscriberMethod : subscriberMethods) {
                    subscribe(subscriber, subscriberMethod);
                }
            }
        }
    
        /**
         * 真正的订阅
         *
         * @param subscriber
         * @param subscriberMethod
         */
        private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
            Class eventType = subscriberMethod.getEventType();
            Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
            CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
            if (subscriptions == null) {
                subscriptions = new CopyOnWriteArrayList<>();
                subscriptionsByEventType.put(eventType, subscriptions);
            }
            int size = subscriptions.size();
            for (int i = 0; i <= size; i++) {
                if (i == size) {
                    //向订阅集合中加入订阅
                    subscriptions.add(i, newSubscription);
                    break;
                }
            }
    
            List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
            if (subscribedEvents == null) {
                subscribedEvents = new ArrayList<>();
                typesBySubscriber.put(subscriber, subscribedEvents);
            }
            subscribedEvents.add(eventType);
    
        }
    

      EventBus.getDefault().post(eventObj)

     /**
         * 发送事件方法
         *
         * @param eventObj
         */
        public void post(Object eventObj) {
            PostingThreadState postingThreadState = currentPostingThreadState.get();
            List<Object> queue = postingThreadState.getEventQueue();
            queue.add(eventObj);
            postingThreadState.setMainThread(isMainThread());
            //缺少一个发送事件的线程
            Class<?> clazz = eventObj.getClass();
            List<Subscription> subscriptions = subscriptionsByEventType.get(clazz);
            if (subscriptions != null) {
                //循环遍历Subscriptions,
                for (Subscription subscription : subscriptions) {
                    //分发事件
                    postToSubscription(subscription, eventObj, postingThreadState);
    
                }
            }
    
        }
    
        /**
         * 返回true为主线程,否则为子线程
         *
         * @return
         */
        private boolean isMainThread() {
            return Looper.myLooper() == Looper.getMainLooper();
        }
    
        /**
         * 对事件进行分发
         *
         * @param subscription
         * @param eventTypeObj
         */
        private void postToSubscription(Subscription subscription, Object eventTypeObj, PostingThreadState postingThreadState) {
            switch (subscription.getSubscriberMethod().getThreadMode()) {
                case POSITION:
                    invokeSubscriber(subscription, eventTypeObj);
                    break;
                case MAIN:
                    if (isMainThread()) {
                        invokeSubscriber(subscription, eventTypeObj);
                    } else {
                        mainThreadHandlerPoster.enqueue(subscription, eventTypeObj);
                    }
                    break;
                case MAIN_ORDERD:
                    if (mainThreadHandlerPoster != null) {
                        mainThreadHandlerPoster.enqueue(subscription, eventTypeObj);
                    } else {
                        invokeSubscriber(subscription, eventTypeObj);
                    }
                    break;
                case BACKGROUND:
                    if (backgroundPoster != null) {
                        backgroundPoster.enqueue(subscription, eventTypeObj);
                    } else {
                        invokeSubscriber(subscription, eventTypeObj);
                    }
                    break;
                case ASYNC:
                    asyncPoster.enqueue(subscription, eventTypeObj);
                    break;
            }
        }
    
        /**
         * 执行事件的具体方法
         *
         * @param subscription
         * @param eventTypeObj
         */
        public void invokeSubscriber(Subscription subscription, Object eventTypeObj) {
            try {
                subscription.getSubscriberMethod().getMethod().setAccessible(true);
                subscription.getSubscriberMethod().getMethod().invoke(subscription.getSubscriber(), eventTypeObj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    

      EventBus.getDefault().unRegister(subscriber)

     /**
         * 取消注册方法
         * 取消注册其实就清除两个 集合就行了,一个是Subscriptions集合,一个是typesBySubscriber集合
         *
         * @param subscriber
         */
        public void unRegister(Object subscriber) {
            List<Class<?>> eventTypes = typesBySubscriber.get(subscriber);
            if (eventTypes != null) {
                for (Class<?> clazz : eventTypes) {
                    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(clazz);
                    for (Subscription subscription : subscriptions) {
                        if (subscriber == subscription.getSubscriber()) {
                            subscriptions.remove(subscription);
                        }
                    }
                }
                typesBySubscriber.remove(subscriber);
            }
    
        }
    

      完整的源代码我发布到了github上欢迎大家下载,地址如下:myeventbuslib

  • 相关阅读:
    龙井和碧螺春的功效与作用
    064 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 无参带返回值方法
    063 01 Android 零基础入门 01 Java基础语法 08 Java方法 01 无参无返回值方法
    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用
    061 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 08 一维数组总结
    060 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 07 冒泡排序
    059 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 06 增强型for循环
    058 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 05 案例:求数组元素的最大值
    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和
    056 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 03 一维数组的应用
  • 原文地址:https://www.cnblogs.com/tony-yang-flutter/p/12463490.html
Copyright © 2011-2022 走看看