otto框架解析

代码星冰乐

专注成就未来

首页 归档 关于

otto框架解析

Aug 28, 2016 | ChanghuiN | Android | 阅读
文章目录
  1. 1. 基本原理
  2. 2. 构造函数
  3. 3. 注册
  4. 4. 发送事件
  5. 5. 取消订阅

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/dea7/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。


由于版权原因,请阅读原文 --> otto框架解析

关注我们

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/dea7/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/dea7/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

otto是square公司出的一个事件库(pub/sub模式),用来简化应用程序之间的通讯。

基本原理

框架中有两个注解(@Produce、@Subscribe),分别代表生产者,订阅者。在发布事件时,框架会通过识别方法是否含有@Subscribe以及参数来确定相应的方法,然后通过反射执行所有符合该事件的方法。

构造函数

Bus有5个构造函数,但最宗都会实现Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder)构造方法,其中:
enforcer为Bus指定所在线程,可通过ThreadEnforcer.ANT或者ThreadEnforcer.MAIN来指定,默认为在主线程执行。
identifier相当与给Bus起一个名字,会在toString方法中使用。
handlerFinder是整个event bus的核心,不需要用户来指定,它用于在register、unregister的时候查找所有的Produce、Subscribe。默认的参数为HandlerFinder.ANNOTATED,也就是说HanlderFinder的具体实现类为AnnotatedHandlerFinder。
Bus使用时一般采用单例模式。

注册

如果一个类对某些事件感兴趣,则需要调用register方法来注册监听。
register会首先调用handlerFinder.findAllProducers(object)来找到所有使用了@Produce注解的方法。findAllProducers其实是委托AnnotatedHandlerFinder.findAllProducers方法。
在调用完findAllProducers方法之后,会遍历传入的监听类的Produce方法,并且根据Produce方法的返回类型,来检查是否有对应的Subscribe存在,如果有的话,就会调用Subscribe方法,并将Producer的返回值传入。

1
2
3
4
5
6
7
8
9
10
11
12
Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
for (Class<?> type : foundProducers.ketSet() ) {
final EventProducer producer = foundProducers.get(type);
EventProducer previousProducer = producersByType.putIfAbsent(type, producer);
...
Set<EventHandler> handlers = handlersByType.get(type);
if (handlers != null && !handlers.isEmpty()) {
for (EventHandler handler : handlers) {
dispatchProducerResultToHandler(handler, producer);
}
}
}

这里需要注意的是,Bus对象两个Map类型的常量,用来缓存所有的Producer和Subscriber。
找到了所有的Producers之后,就是调用handlerFinder.findAllSubcribers(object)来寻找object中使用@Subscriber注解的方法,过程和findAllProducers类似,唯一不同的是一个事件中可以有多个Subscribe,却只能有一个Producer,根据他们的返回值类型可以判断。

找到监听类所有的subscribe方法自后,就需要查看Bus中有和这些subscribe对应的producer方法,如果有的话,就会立即调用subscribe方法。这也就是文档上说的,一但有新的subscribe订阅了某一事件,并且该事件有对应的producer,那么subscribe方法就会立即被调用,并且传入producer方法的返回值。

发送事件

post(Object event)方法用来发送事件给所有的订阅者。它接受的是一个Object类型,说明otto的事件可以是任意类型的对讲。

1
2
3
4
Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass());
for (Class<?> eventType :disPatchTypes) {
...
}

post方法首先会获取所有event对象的父类,饭后遍历这些父类,找到他们所有的订阅者,发送事件,这表明任何订阅了event对象的订阅者也都会收到event事件。

值得注意的是Otto使用ThreadLocal类型来存放事件队列,这样极大的简化了多线程模式下的开发。

取消订阅

unregister方法做的事情和register刚好相反,从缓存中清除所有和当前监听对象相关的producers和subscribers。

关注我们

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/dea7/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分享
Android源码解析
System方法总结
微信关注我们
分类
  • Android8
  • Go4
  • Java59
  • Kafka,Java1
  • Kotlin2
  • Linux1
  • MapReduce1
  • Python2
  • Raft1
  • Redis1
  • ThreadPoolExecutor1
  • go1
  • 工具1
  • 总结8
  • 旅游日记1
标签
Nginx ChanghuiN haifeiWu Android Java 设计模式 hexo Kotlin 算法 MySQL 源码解析 Python Redis golang web Kafka 配置中心 总结 性能优化 旅游日记 Shell Go 问题排查 译文 Docker Spring Boot 工具 学习笔记 WebFlux 性能测试 go 散列表 源码 netty Raft
最近文章
  • Kafka的日志复制机制
  • 从20到21
  • go 并发编程
  • 【译】了解Linux CPU负载-您何时应该担心?
  • Zookeeper 与分布式锁
  • 基于Redis的分布式锁到底安全吗?
  • 【译】Raft 学生指南
  • ThreadPoolExecutor 的简单梳理
  • MapReduce 的简单实现
  • 使用 Map 实现策略模式
福利专区
    免费SSL证书
      阿里云红包
        腾讯云专属福利
        Copyright © 2021 代码星冰乐. Powered by ChanghuiN. 版权所有 晋ICP备15001365号
        特别感谢: 云服务器服务商 、 CDN 服务商