EventBus 利弊与源码解析

通过事件总线EventBus/AsyncEventBus进行JAVA模块解耦 (史上最全) EventBus是google的Guava库中的一个处理组件间通信的事件总线,它基于发布/订阅模式,实现了多组件之间通信的解耦合,事件产生方和事件消费方实现解耦分离,提升了通信的简洁性。为什么使用事件总线?当一个事件的发生(事件产生方),需要触发很多事件(事件消费方)的时候,我们通常会在事件产生方中,分别的去调用那些事件消费方,这样往往是很浪费资源。事件的产生方事件的消费方,产生了极大的耦合,如果我们要改动某一个事件消费方,我们很可能还要改动事件的产生方。 阅读详情

原文连接, 转载请注明作者和原文连接(@woaitqs
,woaitqs.github.io)

EventBus 需要解决的问题

在日常编码里面,我们会遇到很多网络请求,数据库操作等等,一般情况下这些操作都是通过观察者模式来实现的。通过Volley来简单举个例子:

ImageRequest request = new ImageRequest(url,
    new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap bitmap) {
            mImageView.setImageBitmap(bitmap);
        }
    }, 0, 0, null,
    new Response.ErrorListener() {
        public void onErrorResponse(VolleyError error) {
            mImageView.setImageResource(R.drawable.image_load_error);
        }
    });

此时,你会发现并且开始思考一个问题,如果很多观察者模式需要使用了? 比如,你正在开发一个东西,需要监听网络状态变化,App的安装情况,内容的下载情况。当存在很多观察者模式,「如何将这些事件通知到监听者」是可以复用的模块,这就是EventBus存在的意义。这里需要大家想明白一个问题,观察者模式本身就是一个可以复用的模块。

  • 内容下载模块
  • 电量监听模块
  • App按照通知

他们都可以通过EventBus将自身的事件发布出去,使用者只需要在这个模块里面,注册对于自己感兴趣的内容就行。

EventBus 发布和接收模块

EventBus 带来的好处和引入的问题

好处比较明显,就是独立出一个发布订阅模块,调用者可以通过使用这个模块,屏蔽一些线程切换问题,简单地实现发布订阅功能。

坏处可能比较隐晦,但这些需要足够引起我们的重视

  • 大量的滥用,将导致逻辑的分散,出现问题后很难定位。
  • 没办法实现强类型,在编译的时候就发现问题,(Otto实现了这个,但性能有问题)。在实现上通过一个很弱的协议,比如onEvent{XXX}, {XXX}表示ThreadModel,来实现线程的切换。后面在代码解析的时候,会说明这个问题。
  • 代码可读性有些问题,IDE无法识别这些协议,对IDE不友好。

总得来说,如果项目里面有大量的事件交互,那么还是可以通过EventBus来实现,否则还是推荐自己在模块内部实现观察者模式

EventBus 源码解析

EventBus.java

源码阅读从外观类开始,这里是 EventBus.java,核心接口都在这个类里面实现,对内容感兴趣的调用方使用 register 方法,当有事件产生的时候,会在onEvent的时候收到相应的回调。

register(Object object);

registerSticky(Object object);

unRegister(Object object);

post(Object object);

先看看初始化部分,看看如何实现单例的(可选的)。

// volatile 这里是需要重视的,这个关键字保证了defaultInstance在不同线程间的可见性,也就是说在多线程环境下,看到的仍然是最新修改的值。
static volatile EventBus defaultInstance;
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
    // 这一步不存在线程问题,volatile保证了。如果没有defaultInstance实例化出来,
    if (defaultInstance == null) {
        synchronized (EventBus.class) {
            // 进入同步块的时候,不能保证defaultInstance没有被实例化出来,所以需要进行double-check
            if (defaultInstance == null) {
                defaultInstance = new EventBus();
            }
        }
    }
    return defaultInstance;
}

// 这里实现的时候,考虑的是defaultInstance 不一定是每个人都需要创建的,否则没必要使用lazy的实现方式
// 下面是一种实现方式
static {
    defaultInstance = new EventBus();
}

EventBus实现了EventBusBuilder,通过Builder的方式使得构建的时候更加容易

public static EventBusBuilder builder() {
    return new EventBusBuilder();
}

下面重点看看register(Object subscriber, boolean sticky, int priority)方法

private synchronized void register(Object subscriber, boolean sticky, int priority)
BroadcastReceiver、EventBus的优缺点 今天在知乎上,看到一个关于android中本地广播和eventbus选择的问题,感觉说的挺好的,我在这里记录一下; 本地广播是相对消耗时间、空间最多的一种方式,但是大家都知道,广播是四大组件之一,许多系统级的事件都是通过广播来通知的,比如说网络的变化、电量的变化,短信发送和接收的状态,所以,如果android系统进行相关的通知,还是要选择本地广播;在BroadcastReceiver的 onR 阅读详情

相关推荐

EventBus 3.X使用、适用场景、优缺点介绍

一、EventBus 介绍 EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。 二、EventBus使用介绍 首先你要为你的app添加依赖库: ...

xt173160769的博客 2473

面试官:EventBus了解过吗?底层原理?

EventBus了是一种用于在不同组件或模块之间进行通信的机制,通常用于发布-订阅(Publish-Subscribe)模式。它允许一个组件发布事件,而其他组件可以订阅这些事件并在事件发生时做出响应。EventBus 在前端开发中非常有用,尤其是在大型单页应用(SPA)中,可以帮助解耦组件之间的依赖关系。

weixin_63169162的博客 1911

EventBus使用详解

创建一个简单的Java类作为事件对象,该类通常只包含要传递的数据和相应的getter/setter方法。

卡拉米 1705

EventBus源码详解架构分析,使用EventBus会造成什么弊端,带你复现整个思路历程...

本专栏专注分享大型Bat面试知识,后续会持续更新,喜欢的话麻烦点击一个star 面试官: 为什么会用到EventBus,EventBus源码详解架构分析,使用EventBus会造成什么弊端心理分析:eventbus对程序员相爱相恨,爱 爱在太方便了,恨 恨在对程序的可读性有致命的伤害,小公司会用但面试的时候不会考,大公司不会用,但面试的时候使劲考。从该文中我们可以...

273

EventBus源码解析

参考 EventBus源码解析EventBus 利弊源码解析 Android EventBus源码解析 带你深入理解EventBus

zuochunsheng的博客 289

Android工程师能力评估体系:分层分维度考察实战能力

Android开发领域,技术栈涵盖从Java/Kotlin基础到Framework系统机制。Handler消息循环、Binder跨进程通信性能优化工具链,是衡量候选人能否定位线上疑难Bug的关键指标。一套科学的能力评估体系,需要从基础层、应用层、系统层到工程层分层考察,结合代码笔试、项目深挖实战复盘,才能避免“背题库式”面试的失真。在团队招聘个人成长中,掌握Binder原理、理解Gradle构建CI/CD链路,不仅是高级工程师的必修课,也是构建Android工程化能力的重要基石。基于此,一套可落地的

weixin_32496547的博客 223

EventBus

(一)介绍 1,EvenetBus是一种发布-订阅事件总线. 代码简洁,开销小,并很好的实现了发送者和接收者的解耦.(是一种观察者模式) 2,三要素: Event:事件 Publisher:发布者,可以在任意线程发布事件 Subscrible:订阅者, 3,通常情况下安卓下数据的传递有下面几种方法: 3.1.通过intent传递,包括显式意图和隐式意图,广播(Broa...

lixpjita39的专栏 606

事件总线和消息队列差别

**事件总线**:通常采用发布/订阅模式,其中消息(事件)被广播给所有订阅了特定事件类型的侦听器或处理器。- **事件总线**:通常提供尽力而为的传递保证,消息可能会丢失,特别是如果事件的生成速度超过了消费者处理速度。- **事件总线**:提供了较高的解耦性,生产者和消费者之间不需要直接了解对方的存在,它们只总线交互。- **事件总线**:可以实现组件之间的实时通信,事件一旦发布,所有订阅者理论上可以立即收到。- **事件总线**:通常不保证消息的持久化,消息可能会因为系统故障而丢失。

leijmdas的专栏 1142

Android常用的组件间通信方式

1.startActivityForResult 适用于两个Activity之间一对一的交互。 2.LocalBroadcastManager 使用条件:只要有Context即可。优点:发送方的Context可以是非UI组件的,而EventBus就不可以。适用场景是:后台收到服务端的推送消息后,多个相关页面要刷新页面或显示未读小红点。 使用方法: 2.1发送方: Intent

chwnpp2的专栏 1785

Android开源框架之EventBus(一)

一、简介 EvenetBus是一种发布-订阅事件总线.代码简洁,开销小,并很好的实现了发送者和接收者的解耦.(是一种观察者模式) 二、用到的设计模式 1、单例模式:一个类有且仅有一个实例,并且自行实例化向整个系统提供。 2、建造者模式:将一个复杂对象的构造它的表示分离,使同样的构建过程可以创建不同的表示。使用Builder 3、观察者模式:定义了对象之间的一对多依赖,当一个对象改变状态时,它...

u013087553的博客 284

EventBus的特性及简单的使用介绍

EventBus是一个用于AndroidJava的开源库,使用发布者/订阅者模式(publisher/subscriber pattern)实现松散(loose)耦合(coupling)。EventBus使中央通信仅用几行代码就能解耦类(decouple classes)——简化代码(simplifying the code)、消除依赖(removing dependencies)和加速应用程序...

WindfallSheng的博客 897

EventBus 中文文档,android性能优化面试

EventBus 帮您可以处理线程问题:事件可以发布到发布线程不同的线程中。一个常见的用例是处理 UI 变化。对于 Android,UI 改变必须发生在 UI(main)线程中。另一方面,网络请求或其他任何耗时的任务不得在主线程上运行。EventBus 可以帮助你处理这些问题,并 UI 线程保持协调(您不必深入到线程转换,比如使用 AsyncTask 等)。在 EventBus 中,您可以使用四种线程模式之一来指定调用事件处理方法的线程。

m0_56169789的博客 858

EventBus3.0 性能提升之添加索引

EventBus3.0 源码解析 一文中,在分析Subscriber的register()过程中,说到过一个方法方法findUsingReflectionInSingleClass,在该方法的作用是在RunTime期间通过反射获取Subscriber中的SubscriberMethod。 这样就会产生一个问题,在RunTime期间使用反射对程序运行的性能有较大影响。这里我们可以看看EventBu...

zhangke 2564

Illegal onEvent method, check for typos: EventBus错误

错误并不是本人遇到的,是一个朋友遇到的(3.0以下的EventBus) 他是这样的在Activity基类里面,设置是否注册EventBus,然后复写onEventMainThread 然后这个方法里面是直接掉了另外一个OnEventComming方法,结果一运行就报错了,如下 我直接转到EventBus查看,追踪到如下代码 上图的代码,大概是通过反射获取所有方法,过滤不是p

玩火猴子 1662

Android使用EventBus遇到的坑!

AndroidEventBus使用

qq97206858的博客 1万+

AndroidEventBus 3.x使用APT提升性能

EventBus 3.0除了支持注解,还有一个鲜为人知的功能,那就是使用APT来搜集SubscriberMethod。这是一个可选的功能,需要额外添加支持。使用APT可以在项目编译期间搜集所有的SubscriberMethod,默认是在运行期间通过反射去搜索subscriber,这样势必存在性能损耗。

devnn的专栏 1369

事件总线 EventBus

EventBus 顾名思义,事件总线,是一个轻量级的发布 - 订阅模式的应用模式。相比于 MQ 更加简洁,轻量,它可以在一个小系统模块内部使用EventBus允许组件之间通过发布 - 订阅进行通信,而不需要组件之间显示的注册。它专门设计为了代替使用显示注册的传统的 Java 进程内事件分发。它不是通用的发布-订阅系统,也不是用于进程间通信的。

张三李四王五老六 5668

【Andorid】EventBus浅探

订阅者(Subscriber)把自己想订阅的事件(Event)注册(register)到调度中心(EventBus),当发布者(Publisher)发布该事件到调度中心时,也就是该事件触发时,由调度中心统一调度订阅者注册到调度中心的处理代码(onEvent())。(发布/订阅者模式观察者模式并不完全一样)粘性事件的特点在于能够在发送事件之后再进行订阅,依然可以接收到该事件。这普通事件不同,普通事件遵循先注册订阅者后发布事件的顺序,而粘性事件允许先发布后注册的操作方式。

2303_79296612的博客 892
上一篇: 对Tineye搜索引擎的猜想
下一篇: Volley 源码解析
superjimmy
博客等级 码龄16年 89粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值