EventBus源码分析

 

一、         EventBus简介

1.1EventBus

EventBus 是一个 Android 事件发布/订阅框架,通过解耦发布者和订阅者简化Android 事件传递,这里的事件可以理解为消息,本文中统一称为事件。事件传递既可用于 Android 四大组件间通讯,也可以用户异步线程和主线程间通讯等等。

传统的事件传递方式包括:Intent、Handler、BroadCastReceiver、Interface 回调,相比之下 EventBus 的优点是代码简洁,使用简单,并将事件发布和订阅充分解耦。可简化 Activities, Fragments, Threads, Services 等组件间的消息传递,可替代Intent、Handler、BroadCast、接口等传统方案,更快,代码更小,50K 左右的 jar 包,代码更优雅,彻底解耦。

1.2、概念

事件(Event):又可称为消息,本文中统一用事件表示。其实就是一个对象,可以是网络请求返回的字符串,也可以是某个开关状态等等。事件类型(EventType)指事件所属的 Class。

事件分为一般事件和 Sticky 事件,相对于一般事件,Sticky 事件不同之处在于,当事件发布后,再有订阅者开始订阅该类型事件,依然能收到该类型事件最近一个Sticky事件。

订阅者(Subscriber):订阅某种事件类型的对象。当有发布者发布这类事件后,EventBus 会执行订阅者的onEvent 函数,这个函数叫事件响应函数。订阅者通过register 接口订阅某个事件类型,unregister 接口退订。订阅者存在优先级,优先级高的订阅者可以取消事件继续向优先级低的订阅者分发,默认所有订阅者优先级都为0。

发布者(Publisher):发布某事件的对象,通过 post 接口发布事件。

1.3、订阅者、发布者、EventBus 关系图

EventBus 负责存储订阅者、事件相关信息,订阅者和发布者都只和
EventBus 关联。

事件响应流程

订阅者首先调用 EventBus的 register 接口订阅某种类型的事件,当发布者通过 post 接口发布该类型的事件时,EventBus 执行调用者的事件响应函数。

二、        
EventBus优势

2.1、对比Java监听器接口(Listener Interfaces

在Java中,特别是Android,一个常用的模式就是使用“监听器(Listeners)”接口。在此模式中,一个实现了监听器接口的类必须将自身注册到它想要监听的类中去。这就意味着监听与被监听之间属于强关联关系。这种关系就使得单元测试很难进行开展。

2.2、对比本地广播管理器(LocalBroadcastManager

另一项技术就是在组件间通过本地广播管理器(LocalBroadcastManager)进行消息的发送与监听。虽然这对于解耦有很好的帮助,但它的API不如EventBus那样简洁。此外,如果你不注意保持Intent extras类型的一致,它还可能引发潜在的运行时/类型检测错误。

使用EventBus不仅使代码变得清晰,而且增强了类型安全(type-safe)。当用Intent传递数据时,在编译时并不能检查出所设的extra类型与收到时的类型一致。所以一个很常见的错误便是你或者你团队中的其他人改变了Intent所传递的数据,但忘记了对全部的接收器(receiver)进行更新。这种错误在编译时是无法被发现的,只有在运行时才会发现问题。

而使用EventBus所传递的消息则是通过你所定义的Event类。由于接收者方法是直接与这些类实例打交道,所以所有的数据均可以进行类型检查,这样任何由于类型不一致所导致的错误都可以在编译时刻被发现。

另外就是你的Event类可以定义成任何类型。通常会为了表示事件而显式地创建明确命名的类,你也通过EventBus发送/接收任何类。通过这种方法,你就不必受限于那些只能添加到Intent extras中的简单数据类型了。例如,你可以发送一个和ORM模型类实例,并且在接收端直接处理与ORM操作相关的类实例。

三、        
EventBus使用

3.1基本使用

3.2具体案例

3.3 onEvent函数使用解析

前一篇给大家装简单演示了EventBus的onEventMainThread()函数的接收,其实EventBus还有另外有个不同的函数,他们分别是:

1、onEvent

2、onEventMainThread

3、onEventBackgroundThread

4、onEventAsync

这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下面的订阅函数实现的。

onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。

onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中更新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。

onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。

onEventAsync使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.

3.4 EvetntBus3.0使用解析

注册一般是在 onCreate 和 onStart 里注册,尽量不要在 onResume,可能出现多次注册的情况,比如下面这个异常:

取消注册 要写到 onDestroy 方法里,不要写到 onStop 里,有时会出现异常的哦

EventBus 3 和之前版本的 EventBus 不兼容,这里采用注解的方法来接收事件,四种注解 @Subscrible、@Subscrible(threadMode = ThreadMode.ASYNC)、@Subscribe(threadMode
= ThreadMode.BACKGROUND)、@Subscribe(threadMode = ThreadMode.MAIN)分别对应之前的 onEvent()、onEventAsync()、onEventBackground()、onEventMainThread()。

EventBus 3 采用注解后,方法名没有限制了,参数只有一个,和发送者 post 的参数对应配对,在未声明 threadMode 时,默认的线程模式为 ThreadMode.POSTING,只有在该模式下才可以取消线程。

由于可在任何地方都可以 post 一个事件,那么在不同线程之间传递事件,比如在工作线程传递一个事件更新UI线程中的一个控件,则需要注意 threadMode 的切换。

如果遇到订阅事件无法执行的情况,分析后发现是订阅事件的 Activity 还未执行的原因。找到原因就好办了,这时候就需要用到 postSticky。

四、        
EventBus源码解析

4.1 register

EventBus.getDefault().register(this);
 EventBus.getDefault()其实就是个单例,和我们传统的getInstance一个意思:

使用了双重判断的方式,防止并发的问题,还能极大的提高效率。

register公布给我们使用的有4个:

调用内部类SubscriberMethodFinderfindSubscriberMethods方法,传入了subscriber class,以及methodName,返回一个List<SubscriberMethod>

那么不用说,肯定是去遍历该类内部所有方法,然后根据methodName去匹配,匹配成功的封装成SubscriberMethod,最后返回一个List

继续回到register:

到此,我们register就介绍完了。

你只要记得一件事:扫描了所有的方法,把匹配的方法最终保存在subscriptionsByEventTypeMapkeyeventType valueCopyOnWriteArrayList<Subscription> )中;

eventType是我们方法参数的ClassSubscription中则保存着subscriber,
subscriberMethod
method, threadMode, eventType, priority;包含了执行改方法所需的一切。

4.2 post

到此,我们完整的源码分析就结束了,总结一下:register会把当前类中匹配的方法,存入一个map,而post会根据实参去map查找进行反射调用。分析这么久,一句话就说完了~~

其实不用发布者,订阅者,事件,总线这几个词或许更好理解,以后大家问了EventBus,可以说,就是在一个单例内部维持着一个map对象存储了一堆的方法;post无非就是根据参数去查找方法,进行反射调用。

 

 

原文地址:https://www.cnblogs.com/fuyaozhishang/p/9944653.html

时间: 2024-07-28 18:38:50

EventBus源码分析的相关文章

EventBus 2.4 源码分析

EventBus简介 本篇基于EventBus 2.4撰写. Android optimized event bus that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality. 上面是从官方repo拉来的代码,大致是说简化的组件之间的交流通信,减少代码,提高质量. 其实和EventBus最早是在qzone的代码里认识的,空间内部有一个

EventBus框架源码分析

开源项目 上周又手动撸了一遍EventBus实现,同时上传EventBus的中文注释源码到Github上,欢迎大家fork&star. EventBusAnalysis EventBus 基础概念 EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递.事件传递既可以用于Android四大组件间的通讯,也可以用于用户异步线程和主线程间通讯等. 传统的事件传递方法包括:Handler,BroadCastReceiver,interface回调,相比

EventBus 3.0使用与源码分析

EventBus简介 EventBus is a publish/subscribe event bus optimized for Android. EventBus 是一个基于发布/订阅模式的事件总线.其模型图如下 从图可知,EventBus分为四个角色,消息发布者.事件总线.事件.消息订阅者.消息发布者把Event(消息)post(发送)到事件总线,事件总线维护一个事件队列,把Event发送到Subscriber(消息订阅者),调用其onEvent方法进行相应的处理. 1.特点 - 简化组

EventBus使用详情、源码分析和注意事项

基本介绍 EventBus主要用于事件的订阅和发布,主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.官方文档介绍了EventBus的很多优点,归纳一下就是三个优点:小,快和方便.以下会围绕初步使用.使用进阶.源码分析和注意事项来讲解,如果需要快速上手,只要看完初步使用和注意事项就可以了. 初步使用 EventBus的使用非常简单,主要使用到以下三个方法: //注册EventBus EventBus.getDef

8.源码分析---从设计模式中看SOFARPC中的EventBus?

我们在前面分析客户端引用的时候会看到如下这段代码: // 产生开始调用事件 if (EventBus.isEnable(ClientStartInvokeEvent.class)) { EventBus.post(new ClientStartInvokeEvent(request)); } 这里用EventBus调用了一下post方法之后就什么也没做了,就方法名来看是发送了一个post请求,也不知道发给谁,到底有什么用. 所以这一节我们来分析一下EventBus这个类的作用. 首先我们来看一下

Android EventBus源码解析, 带你深入理解EventBus

上一篇带大家初步了解了EventBus的使用方式,详见:Android EventBus实战 没听过你就out了,本篇博客将解析EventBus的源码,相信能够让大家深入理解该框架的实现,也能解决很多在使用中的疑问:为什么可以这么做?为什么这么做不好呢? 1.概述 一般使用EventBus的组件类,类似下面这种方式: [java] view plain copy public class SampleComponent extends Fragment { @Override public vo

Android:Otto源码分析

Otto源码分析 Otto是一个轻量级的EventBus,它的使用非常简单,我们使用一个Bus的单例,所有需要产生事件(@Produce bus.post(new YourEvent(-)))或者处理事件(@Subscribe)的对象,在create时register,销毁destroy时unregister即可. 使用 @Subscribe 订阅事件,也就是事件的处理者,它有且仅有一个参数YourEvent,每一个Subscribe对应处理一个YourEvent.Event用于连接(匹配)po

LocalBroadcastManager源码分析

源码分析 /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * htt

Android 开源项目源码分析第一期正式发布

由 Trinea 发起.几十名 Android 开发者参与的Android 开源项目源码分析第一期正式发布. 从简介.总体设计.流程图.详细设计全方面分析开源库源码,第一期包括 10 个著名开源库及 5 个公共技术点的全面介绍. 分析文档 作者 Volley 源码解析 grumoon Universal Image Loader 源码分析 huxian99 Dagger 源码解析 扔物线 EventBus 源码解析 Trinea xUtils 源码解析 Caij ViewPagerindicat