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

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

  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();
        }
    }
时间: 2024-10-06 09:26:13

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

【第五篇】androidEventbus源代码阅读和分析之unregister代码分析

代码里面注销eventbus一般我们会在onDestory里面这么写: 1 EventBus.getDefault().unregister(this); 然后走到unregister里面去看看: 1 /** 2 * @param subscriber 3 */ 4 public void unregister(Object subscriber) { 5 if (subscriber == null) { 6 return; 7 } 8 synchronized (this) { 9 mMet

【第四篇】androidEventbus源代码阅读和分析

1,分析androidEventbus的注册源代码: 我们在使用androidEventbus的第一步是注册eventbus,如下代码: EventBus.getDefault().register(this); 首先获取eventbus对象,采用单利模式实现获取对象: Eventbus.java里面 public static EventBus getDefault() { if (sDefaultBus == null) { synchronized (EventBus.class) { i

Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 一 图库数据管理 Gallery2的数据管理 DataManager(职责:管理数据源)- MediaSource(职责:管理数据集) - MediaSet(职责:管理数据项).DataManager中初始化所有的数据源(LocalSo

恶意代码分析实战

恶意代码分析实战(最权威的恶意代码分析指南,理论实践分析并重,业内人手一册的宝典) [美]Michael Sikorski(迈克尔.斯科尔斯基), Andrew Honig(安德鲁.哈尼克)著   <恶意代码分析实战>是一本内容全面的恶意代码分析技术指南,其内容兼顾理论,重在实践,从不同方面为读者讲解恶意代码分析的实用技术方法. <恶意代码分析实战>分为21章,覆盖恶意代码行为.恶意代码静态分析方法.恶意代码动态分析方法.恶意代码对抗与反对抗方法等,并包含了 shellcode分析

免费的Lucene 原理与代码分析完整版下载

Lucene是一个基于Java的高效的全文检索库.那么什么是全文检索,为什么需要全文检索?目前人们生活中出现的数据总的来说分为两类:结构化数据和非结构化数据.很容易理解,结构化数据是有固定格式和结构的或者有限长度的数据,比如数据库,元数据等.非结构化数据则是不定长或者没有固定格式的数据,如图片,邮件,文档等.还有一种较少的分类为半结构化数据,如XML,HTML等,在一定程度上我们可以将其按照结构化数据来处理,也可以抽取纯文本按照非结构化数据来处理.非结构化数据又称为全文数据.,对其搜索主要有两种

PostgreSQL代码分析,查询优化部分,pull_ands()和pull_ors()

PostgreSQL代码分析,查询优化部分. 这里把规范谓词表达式的部分就整理完了,阅读的顺序如下: 一.PostgreSQL代码分析,查询优化部分,canonicalize_qual 二.PostgreSQL代码分析,查询优化部分,pull_ands()和pull_ors() 三.PostgreSQL代码分析,查询优化部分,process_duplicate_ors ****************************************************************

做完这几道恶意代码分析实战题,十一回来老板就给涨薪!

十一长假要来啦~ 好多同事都提着行李,下班就去几场火车站的,小编这代码还没敲好,担心有人来黑,实在不放心. 话说知己知彼才能百战不殆,放假前把这几个恶意代码的实验做了,谁也动不了我的网站! 不会查找恶意代码的程序员不是好攻城狮.. 尽管恶意代码以许多不同的形态出现,但分析恶意代码的技术是通用的.你选择使用哪项技术,将取决于你的目标.如何防范恶意代码的恶意程序进行恶意行为呢? <恶意代码分析实战>是一本内容全面的恶意代码分析技术指南,其内容兼顾理论,重在实践,从不同方面为读者讲解恶意代码分析的实

linux kernel的中断子系统之(七):GIC代码分析

一.前言 GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器,其architecture specification目前有四个版本,V1-V4(V2最多支持8个ARM core,V3/V4支持更多的ARM core,主要用于ARM64服务器系统结构).目前在ARM官方网站只能下载到Version 2的GIC architecture specification,因此,本文主要描述符合V2规范的GIC硬件及其驱动. 具体GIC硬件的实现形态有两

Linux中断 - GIC代码分析

一.前言 GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器,其architecture specification目前有四个版本,V1-V4(V2最多支持8个ARM core,V3/V4支持更多的ARM core,主要用于ARM64服务器系统结构).目前在ARM官方网站只能下载到Version 2的GIC architecture specification,因此,本文主要描述符合V2规范的GIC硬件及其驱动. 具体GIC硬件的实现形态有两