天天看点

android数据传输利器--Event Bus模式

本文章同时发表在安卓巴士,欢迎大家前去观摩指导。

场景描述:

对于事件总线框架知道的人可能不多,但是进行过Android开发的程序猿们应该都有这样的经历。

1、在开发的过程中遇到过从Activity-A跳转到Activity-B,然后需要在Activity-B处理完某些工作之后回调Activity-A中的某个函数,但Activity又不能手动创建对象来设置一个Listener的情况。

2、遇到在某个Service中更新Activity或Fragment中的界面等组件之间的交互问题。

3、彻底退出应用的功能实现,需要管理activity列表的烦恼。

4、后台下载需要通知各个组件的情况。

5、Fragment之间的通信问题。

有什么用:

事件总线框架简化了Activity、Fragment、Service等组件之间的交互,让代码更简洁,耦合性更低,相比以往的广播或者序列化对象来传递,事件总线就简约和高效了很多。Event Bus模式也被称为Message Bus或者发布者/订阅者(publisher/subscriber)模式,可以让两个组件相互通信,但是他们之间并不相互知晓。

主要作用

1、它承担传输数据的作用

2、它可以解耦模块之间的耦合性

3、简化代码逻辑

4、相比传统方法要更加高效

5、消息可以在任意线程和位置发送

6、接受消息并执行逻辑的方法可以在任意线程运行(可以设置运行的线程)

7、消息与接收者可以是一对多的关系(类似广播)

基本的用法:

市面上这么多的事件总线框架他们的用法都是大同小异的,基本包括下面几个逻辑和使用步骤

1、注册信息订阅者/接收者(可以理解为需要被调用的那一方)

2、定义事件(类似handle中的Message)

3、实现订阅者的方法(消息发送后被调用的方法)

4、发送消息

几个主流框架:

EventBus框架

android数据传输利器--Event Bus模式

EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。

特点:

1、在EventBus中,使用约定来指定事件订阅者以简化使用。即所有事件订阅都都是以onEvent开头的函数,具体来说,函数的名字是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync这四个。简单理解就是需要被调用的方法名称需要按照上面的规则来写,不能自定义。

2、效率高

Github地址和文档:

https://github.com/greenrobot/EventBus

Otto框架

Otto 是Android系统的一个Event Bus模式类库。用来简化应用组件间的通信。

特点:

1、使用注解的方式,@Subscribe 注解告诉Bus该函数订阅了一个事件,该事件的类型为该函数的参数类型;而@Produce注解告诉Bus该函数是一个事件产生者,产生的事件类型为该函数的返回值。函数名称可以自定义。

2、订阅函数默认执行在主线程中

官方网站:

http://square.github.io/otto/

Github地址:

https://github.com/square/otto

AndroidEventBus框架

android数据传输利器--Event Bus模式

这是一个Android平台的事件总线框架, 它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。

AndroidEventBus类似于观察者模式,通过register函数将需要订阅事件的对象注册到事件总线中,然后根据@Subscriber注解来查找对象中的订阅方法,并且将这些订阅方法和订阅对象存储在map中。当用户在某个地方发布一个事件时,事件总线根据事件的参数类型和tag找到对应的订阅者对象,最后执行订阅者对象中的方法。

特点:

1、使用注解的方式,类似Otto,函数名称可以自定义

2、订阅函数支持tag(类似广播接收器的Action)使得事件的投递更加准确,能适应更多使用场景。(可以直接设置执行线程)

Github地址:

https://github.com/bboyfeiyu/AndroidEventBus

中文版文档:

https://github.com/bboyfeiyu/AndroidEventBus/blob/master/README-ch.md

EventBus、AndroidEventBus和Otto对比:

名称 性能 订阅函数执行其他线程是否方便 函数名称是否可以自定义 使用难度
EventBus
AndroidEventBus
Otto 否(要实现接口)

EventBus和Otto性能对比:

在性能上其实已经有了比较广泛的认同,但到底注解方式和约定事件名称这两种之间存在多大的性能差距呢?在这里我拿到了官方的一个测试工具EventBusPerformance来进行一个小测试,对比一下两大类型的框架性能的差别。

本次测试可能不够严谨只给大家作为参考。测试手机为魅族MX3,安卓4.4.4系统

android数据传输利器--Event Bus模式

测试内容:

1. 发消息

分别发送1000条消息到需要在当前线程,主线程,后台线程执行的函数,每个测试10次取平均值。

下面的是一些比较平均的测试结果大家可以参考

android数据传输利器--Event Bus模式
android数据传输利器--Event Bus模式
android数据传输利器--Event Bus模式

从结果中看到,Eventbus在各个测试中比Otto快50%以上,个别测试中比Otto快近4倍。

发送信息到主线程比发送到其他线程要慢。

2. 注册订阅者

两个框架分别注册订阅者1000个,重复10次取平均值。

android数据传输利器--Event Bus模式

上图为选取的比较平均的一次测试。

从结果中很容易看到Eventbus同样是比Otto要快了不少。

3. 注册订阅者但是不注销

两个框架分别注册1000个订阅者不注销,测试10次取平均值

android数据传输利器--Event Bus模式

图为选取的比较平均的一次测试

从测试中可以看到不注销订阅者的速度要比注销订阅者的操作耗时,同样在性能在Eventbus要好一些。

测试总结

1、注解方式和约定事件名称这两种之间性能比较明显,Eventbus性能比较突出。

2、在发送消息的测试中可以知道,同一线程的消息处理要快一些,夸线程操作比较慢,主进程的操作最慢(主进程这个还有待研究大家参考下就好了)。

3、在注册订阅者的测试中不注销订阅者的速度要比注销订阅者的操作耗时,大家看到这个在使用的过程中使用完了一定要记得注销订阅者,这个是会影响性能的!

毕竟我不是专业的测试员,若对测试有疑问欢迎大家下载本测试工具