源码解析之 EventBus

Talk is cheap. Show me the code

前言

最近几年,很多优秀的第三方开源代码出现在我们的眼前,为 app 的开发提供了极大的便利,同时也降低了开发的门槛。现在拿几个框架组合下,再加上几个开源库,一个简单的 app 就出来了。所以在很多的简历中,我们总是能找到这样的描述:

熟悉 xxx 框架,熟练运用第三方 xxx 开源库

这个系列,旨在介绍如何运用开源库的基础上,对这些开源库进行讲解。

由于一般流行的开源库更新的速度都不慢,所以我们这次选取的一般是他最简的版本。但是简单归简单,核心思想还是要有的。相信大家在掌握了核心的思想后,一些旁枝末节就可以顺理成章的理解了。

我们很多的时候往往是只见森林不见树。对于一些几千行甚至几万行代码的开源库不知道从何下手,这时候不如想想是不是可以把不必要的部分先去掉,留下核心的部分,这样理解起来相对就简单对了。而且只要掌握了核心的部分,其他的部分理解起来相对就容易多了。

好了,不多说,这次我们先拿 eventbus 开刀。

什么是EventBus

我们在开发的过程中,免不了需要在各个页面间传递消息。除了最先想到的 Android 四大组件之一的 broadcast 之外,EventBus 应该是我们目前使用最多的通信模块了。如果你没有使用过 EventBus,那么使用广播可能觉得还行,但是一旦你使用过 EventBus,就会觉得使用广播相对来说比较麻烦而且效率也不高。
EventBus 大大的简化了应用程序内部各组件间,组件和后台线程之间的通信。所以最近一年 EventBus 非常流行,甚至到了滥用的地步。

好了,废话不多说,直接上代码。

最新的 EventBus 的 release 版本为 V3.0.0。但是为了竟可能简单的抓住 EventBus 的核心思想,本文以 V1.0.1 版本为基础,再次进行了削减,力求以最少的代码展示最核心的内容。其他的无非是在核心功能上做的扩展。

demo 工程很简单,总共只有 4 个 java 文件,但是用来说明核心原理已经足够了,其中核心的类是 EventBusLite。

工程结构

如何使用

定义事件类

这里直接使用 AnyEvent 作为任意事件的代表。
事件类

注册订阅事件

如下所示,这里使用 register 方法进行订阅事件的注册,区别的地方在于增加了一个 callbackMethodName 的参数,用于指定接收到事件后的处理方法,这块再后面的源码解析中会讲到。
注册事件

发送订阅事件

直接调用 post 方法,不再赘述。
发送事件

源码解析

构造方法

采用的是最简单的单例模式。
构造方法

注册方法

这里对 register 函数进行了改造,第二个参数在源代码中是没有的,onEvent 方法在源代码中是直接以静态字符串的形式存在的,这里为了大家便于理解和调试,所以单独提取出来作为一个入参。

但是这个参数不是随便写的,eventbuslite 中会通过反射机制查找当前注册的类中是否存在该名称所对应的方法。

注册方法

####找到订阅方法
findSubscriberMethods 方法找出一个 subscriberMethods 的集合。也就是传进来的订阅者的订阅方法,然后遍历订阅者中存在的方法,找到匹配后加入到集合中去。

事件的对象为了方便,代码中直接写死去方法中的第一个参数。

下面就来查看该方法的具体实现:
找到订阅方法

开始订阅

subscribe 方法会根据 subscriber 订阅者和 subscriberMethod 订阅方法创建一个 Subscription 订阅对象,对象中存放的是订阅者和订阅方法。
subscriptionsByEventClass 讲事件和订阅对象结合起来。

开始订阅

搜索订阅事件

findEventClasses 通过事件找到订阅者。

搜索定义事件

发送事件

根据事件查找所有的订阅者,并将事件分发给他们。
发送事件

好了,算是流水账式的记了一遍。就像我开头提到的:Talk is cheap. Show me the code。

要理解其中的实现原理,还是直接看源码吧。觉得好的顺便 star 下。

源码地址