EventBus & Otto
来源:互联网 发布:电信网络拓扑分析 编辑:程序博客网 时间:2024/05/22 01:45
一、基本介绍
EventBus 是一个 Android 事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递,这里的事件可以理解为消息,本文中统一称为事件。事件传递既可用于 Android 四大组件间通讯,也可以用户异步线程和主线程间通讯等等。EventBus
EventBus3.0版本有较大的更新,性能上有很大提升。这里主要介绍新版本。
传统的事件传递方式包括:Handler、BroadCastReceiver、Interface 回调,相比之下 EventBus 的优点是代码简洁,使用简单,并将事件发布和订阅充分解耦。类似框架OTTO。
二、EventBus & Otto对比
共同点
1、都是事件总线框架,满足消息/事件传递的同时,也实现了组件间的解耦.
2、注册的共同点都是采用method方法进行一个集成。
3、都采用注解的方式来标注订阅方法(旧版本的EventBus通过固定方法名标记订阅者)
4、大部分规则相同,比如订阅方法只能有一个参数。
5、都不适用进程间通信
不同点
1、OTTO更加轻量级,结构简单。EventBus稍微复杂一些。
2、OTTO默认在主线程中使用,不能在其他线程使用,通过设置ThreadEnforcer可以在任意线程使用,但是消息传递不能指定目标线程,EventBus实现了4种ThreadMode,线程之间消息传递非常灵活。
3、EventBus支持粘性事件,而OTTO不支持。即先发消息,再注册订阅者仍然能够收到消息。
3、OTTO有默认的生产者方法,可以产生默认消息,EventBus没有
三、EventBus的简单使用介绍
定义消息
注册
定义订阅者
发送消息
解绑
四、源码解析
1、EventBus构造
通常我们调用EventBus.getDefault()获取EventBus
这个方法是线程安全的,EventBus的无参构造方法使用默认构建器DEFAULT_BUILDER构造,EventBusBuilder指定了EventBus的一些行为,用于输出log,查错,调试等。
logSubscriberExceptions 指定了收到SubscriberExceptionEvent类型消息时抛出异常的行为,默认为true,打印log,如果为false不输出log
输出的信息有
对logNoSubscriberMessages指定了发送了没有订阅者的消息的行为,默认为true,打印log,如果为false不输出log
输出的信息为
sendSubscriberExceptionEvent指定是否发送SubscriberExceptionEvent,默认为true
操作行为
sendNoSubscriberEvent指定了没有订阅者时的行为,默认为true,发送NoSubscriberEvent这样一个消息
throwSubscriberException指定了订阅方法执行异常时是否抛出异常,默认为false
eventInheritance指定是否发消息给这个事件的父事件对应的订阅者,默认为true。如果为false,只会发消息给类型完全一致的订阅者
ignoreGeneratedIndex指定是否忽略设置索引,这个值默认是false,这段代码中使用的两种解析方式不容易看懂
findUsingReflection利用反射来获取订阅类中的订阅方法信息
findUsingInfo从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
findUsingInfo从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
findUsingInfo执行效率更高一些,默认使用这种。
strictMethodVerification指定是否严格校验,默认为false。严格校验会直接抛出异常
2、注册与解析
注册之后,解析出了所有的订阅方法,方法参数类型
相关映射主要是两个
subscriptionsByEventType的key是订阅者消息类型,value是Subscription,是具体订阅者对应注册对象和方法
typesBySubscriber的key是注册对象,value是对应所有订阅者消息类型的list
解析器是SubscriberMethodFinder这个类,EventBus中有subscriberMethodFinder这个实例,调用
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass)这个方法解析方法信息
如果没有订阅者方法,会抛出异常
如果已经注册过,会抛出异常
如果订阅者是粘性事件,如果粘性事件不为空会直接发送粘性事件。
粘性事件存储结构为
stickyEvents的key是事件类型,Object是对应的具体事件。key,value唯一,说明粘性事件是会被覆盖的。这样可以节省内存开销。
3、发送消息
post线程状态通过ThreadLocal维护,保证线程隔离,不需要加锁,提高运行效率。
经过以下四个方法,事件分发到对应线程的对应订阅者
private void postSingleEvent(Object event, PostingThreadState postingState) private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass)
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread)
void invokeSubscriber(Subscription subscription, Object event)
特别注意线程处理
POSTING:是在当前线程执行
MAIN:抛到主线程
BACKGROUND:如果是在主线程,抛到新线程,如果不是在主线程,就在当前线程执行
ASYNC:抛到新线程中
没有订阅者的消息默认会被重新包装为NoSubscriberEvent,可以做一些全局捕获处理
4、解绑
做一些清理工作,注意不要重复解绑。
刚开始已经说过了,EventBus跟OTTO很像,而 Otto 是基于 Guava 的增强的事件总线,Guava 是google一个很强大的java开源库。EventBus改进是最多的,据说是效率最高的,这个没有做过相关测试。但是从实现上来看,对性能优化处理还是做了很多事情。
0 0
- OTTO-EVENTBUS
- EventBus & Otto
- EventBus和Otto
- Otto EventBus实践
- otto与EventBus对比
- 一种Android EventBus 类库:otto
- EventBus 和Otto的区别
- EventBus, otto, LocalBroadcast的选择
- EventBus, otto, LocalBroadcast的选择
- Otto与EventBus框架比较
- 用RxBus替代EventBus、Otto
- 使用事件总线框架EventBus和Otto
- 使用事件总线框架EventBus和Otto
- 使用事件总线框架EventBus和Otto
- EventBus & Otto的使用和比较
- Android开发之浅谈事件总线框架EventBus和Otto
- 事件总线框架EventBus和Otto学习笔记
- Android组件间通信机解耦——Android EventBus和Otto框架
- 关于SSM的url映射问题
- 武汉大学信息管理学院2016年夏令营笔试试题@7.13
- 安卓学习笔记---ListView选择服务机构,选择完之后可以显示当前的选择项
- Cocos Creator 介绍
- 跟随前端大神的脚步
- EventBus & Otto
- Django导入jquery
- GC算法 垃圾收集器
- 【华为OJ】输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数
- JVM内存结构
- 源码-PL/SQL从入门到精通-第二章-PL/SQL基本概念-Part 1
- 提示框 9款css3 tooltips鼠标悬停显示消息提示框样式(精)
- ssh 远程执行命令
- 从char/wchar_t到TCHAR .