【第五篇】androidEventbus源代码阅读和分析之发送粘性事件和接收粘性事件代码分析

简介: 代码里面发送粘性事件代码如下: // 发送Sticky事件 EventBus.getDefault().postSticky(new User("soyoungboy", "西安财经学院"), "soyoungboy"); ...

代码里面发送粘性事件代码如下:

  1. //  发送Sticky事件
            EventBus.getDefault().postSticky(new User("soyoungboy", "西安财经学院"),
                    "soyoungboy");

     


然后我们进入 postSticky方法里面去:
EventType  是什么?
该类是描述一个函数唯一性的对象,参数类型、tag两个条件保证了对象的唯一性.通过该类的对象来查找注册了相应类型和tag的所有订阅者{@see * Subscription}, 并且在接到消息时调用所有订阅者对应的函数.  
mStickyEvents是什么?
  1.  private List<EventType> mStickyEvents = Collections
                .synchronizedList(new LinkedList<EventType>());

     


是个list集合,用于存储eventType的list集合。
  1.  /**
         * 发布Sticky事件,tag为EventType.DEFAULT_TAG
         * 
         * @param event
         */
        public void postSticky(Object event) {
            postSticky(event, EventType.DEFAULT_TAG);
        }
        /**
         * 发布含有tag的Sticky事件
         * 
         * @param event 事件
         * @param tag 事件tag
         */
        public void postSticky(Object event, String tag) {
            EventType eventType = new EventType(event.getClass(), tag);
            eventType.event = event;
            mStickyEvents.add(eventType);
            // 处理sticky事件
    //        mDispatcher.handleStickyEvent(eventType, null);
        }
这是发布,如何接收粘性事件,我们也看下源码来分析下:
首先要注册粘性事件的eventbus:
  1. EventBus.getDefault().registerSticky(this);
走进 registerSticky代码里面看下:
  1.  /**
         * 以sticky的形式注册,则会在注册成功之后迭代所有的sticky事件
         * 
         * @param subscriber
         */
        public void registerSticky(Object subscriber) {
            this.register(subscriber);
            // 处理sticky事件
            mDispatcher.dispatchStickyEvents(subscriber);
        }

    register代码不进行分析,因为前面讲过,就是将@ subscriber的订阅者对象放入map集合里面去

重点分析下 mDispatcher . dispatchStickyEvents ( subscriber );
  1.  void dispatchStickyEvents(Object subscriber) {
                for (EventType eventType : mStickyEvents) {
                    handleStickyEvent(eventType, subscriber);
                }
            }

     


在往下面走:
根据不同的ThreadMode去调用不同的handler(这里是事件分发器对象)的 handleEvent方法。
ThreadMode是在代码里面通过注解传进来的。
/**
         * 处理单个Sticky事件
         * 
         * @param eventType
         * @param aEvent
         */
        private void handleStickyEvent(EventType eventType, Object subscriber) {
            //从缓存获取eventTypes内容
            List<EventType> eventTypes = getMatchedEventTypes(eventType, eventType.event);
            // 事件
            Object event = eventType.event;
            //循环遍历eventType集合
            for (EventType foundEventType : eventTypes) {
                Log.e("", "### 找到的类型 : " + foundEventType.paramClass.getSimpleName()
                        + ", event class : " + event.getClass().getSimpleName());
                //从订阅者的map集合里面获取指定的订阅者集合的list集合,根据eventType
                final List<Subscription> subscriptions = mSubcriberMap.get(foundEventType);
                if (subscriptions == null) {
                    continue;
                }
                //遍历list集合
                for (Subscription subItem : subscriptions) {
                    final ThreadMode mode = subItem.threadMode;
                    EventHandler eventHandler = getEventHandler(mode);
                    // 如果订阅者为空,那么该sticky事件分发给所有订阅者.否则只分发给该订阅者
                    if (isTarget(subItem, subscriber)
                            && (subItem.eventType.equals(foundEventType)
                                    || subItem.eventType.paramClass
                                    .isAssignableFrom(foundEventType.paramClass))) {
                        // 处理事件
                        eventHandler.handleEvent(subItem, event);
                    }
                }
            }
        }

 

mDispatcher是个事件分发器;
EventDispatcher事件分发器中有三条个ThreadEventHandler:
UIThreadEventHandler
DefaultEventHandler
AsyncEventHandler
都实现了 EventHandler事件处理接口,实现handleEvent方法:
UIThreadEventHandler中实现:
事件处理在UI线程,通过Handler将事件处理post到UI线程的消息队列, UIThreadEventHandler的handleEvent指向 DefaultEventHandler的handleEvent方法;   
  1. /**
         * @param subscription
         * @param event
         */
        public void handleEvent(final Subscription subscription, final Object event) {
            mUIHandler.post(new Runnable() {
                @Override
                public void run() {
                    mEventHandler.handleEvent(subscription, event);
                }
            });
        }

     


 
AsyncEventHandler中实现:默认也是子类为 DefaultEventHandler的handleEvent去实现,重点还是 DefaultEventHandler中的handleEvent的实现。
  1.  /**
         * 将订阅的函数执行在异步线程中
         * 
         * @param subscription
         * @param event
         */
        public void handleEvent(final Subscription subscription, final Object event) {
            mDispatcherThread.post(new Runnable() {
                @Override
                public void run() {
                    mEventHandler.handleEvent(subscription, event);
                }
            });
        }

     


DefaultEventHandler 中实现:
重点是 subscription .targetMethod.invoke( subscription .subscriber.get(),  event ),代码走到最后走到这里,那么到这这里执行了什么操作呢;
执行反射操作,根据参数查找方法,进行反射调用。
 /**
     * handle the event
     * 
     * @param subscription
     * @param event
     */
    public void handleEvent(Subscription subscription, Object event) {
        if (subscription == null
                || subscription.subscriber.get() == null) {
            return;
        }
        try {
            // 执行
            subscription.targetMethod.invoke(subscription.subscriber.get(), event);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

 

相关文章
|
6月前
|
消息中间件 定位技术 调度
《移动互联网技术》第八章 消息与服务:掌握不同类型广播监听方式,以及创建通知的方法
《移动互联网技术》第八章 消息与服务:掌握不同类型广播监听方式,以及创建通知的方法
19 0
|
9月前
|
前端开发 NoSQL Redis
项目实战典型案例5——发送调查问卷流程图例子(将不必要的逻辑放入前端)
项目实战典型案例5——发送调查问卷流程图例子(将不必要的逻辑放入前端)
79 0
|
SQL 测试技术 API
事件风暴过程全体验-下篇
事件风暴过程全体验-下篇
事件风暴过程全体验-下篇
|
定位技术
事件风暴过程全体验-上篇
事件风暴过程全体验-上篇
事件风暴过程全体验-上篇
|
数据采集 消息中间件 XML
【Esper技术专题】一个简单的事件响应功能的案例(2)复杂事件处理引擎
【Esper技术专题】一个简单的事件响应功能的案例(2)复杂事件处理引擎
245 0
一对一聊天平台源码,不同数据缺失处理方法的比较
一对一聊天平台源码,不同数据缺失处理方法的比较
怎样使用阿里云消息服务?
阿里云消息服务(Message Service)是一种高效、可靠、安全、便捷、可弹性扩展的分布式消息服务。MNS能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。 消息服务同时支持各种类型消息推送,其中和短信前后端的无缝整合更高效的为用户提供了大批量短信发送能力。
C# (事件触发)回调函数,完美处理各类疑难杂症!
每次写博客,第一句话都是这样的:程序员很苦逼,除了会写程序,还得会写博客! 废话说多了...... 嘿嘿:本篇标题为:C#  (事件触发)回调函数,完美处理各类疑难杂症。个人理解如下:事件触发也就是触发一个事件,触发的这个事件是通过函数来实现的,而这个函数也就是回调函数。
3666 0
|
存储 数据库 开发框架
Newbe.Claptrap - 一套以 “事件溯源” 和“Actor 模式”作为基本理论的服务端开发框架
Newbe.Claptrap - 一套以 “事件溯源” 和“Actor 模式”作为基本理论的服务端开发框架 本文是关于 Newbe.Claptrap 项目主体内容的介绍,读者可以通过这篇文章,大体了解项目内容。
8881 0
|
JavaScript 容器 前端开发
一些JS事件小片段代码整理收集(持续)
一、js实现 1 2 3 4 5 function AcceptData(num){ 6 document.getElementById("accepDate").value+=num; 7 } 8 9 10 11 12 13 14 15 16  二、input输入框的value传值显示 input输入框中用户输入的值,点击按钮显示在另一个容器之中。
1006 0