EventBus原理
EventBus实现了观察者模式,使用方法非常简单,可参考:有用的Guava(二)
这篇文章主要讲解EventBus的实现原理。
一言以蔽之:EventBus内部有一个map,当register时往map中增加一个元素(key为事件的类型,value为观察者),post时根据事件类型找到观察者之后,对其反射调用。
下面我们从register方法开始:
public void register(Object object) { Multimap<Class<?>, EventHandler> methodsInListener = finder.findAllHandlers(object); handlersByTypeLock.writeLock().lock(); try { handlersByType.putAll(methodsInListener); } finally { handlersByTypeLock.writeLock().unlock(); } }
调用eventBus.register(new Event())时,会将事件类型及观察者(封装为EventHandler)放置在SetMultimap<Class<?>, EventHandler> handlersByType中,这是一个线程安全的对象容器,卸载事件也是在这个容器中做移除操作。根据事件类型查找观察者时使用了策略模式,HandlerFindingStrategy finder做为策略接口,目前只有一个策略实现AnnotatedHandlerFinder(查找带有Subscribe注解的方法)。
有了这样一个map,调用post时只需要根据类型找到观察者就行了:
public void post(Object event) { Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass()); boolean dispatched = false; for (Class<?> eventType : dispatchTypes) { handlersByTypeLock.readLock().lock(); try { Set<EventHandler> wrappers = handlersByType.get(eventType); if (!wrappers.isEmpty()) { dispatched = true; for (EventHandler wrapper : wrappers) { enqueueEvent(event, wrapper); } } } finally { handlersByTypeLock.readLock().unlock(); } } if (!dispatched && !(event instanceof DeadEvent)) { post(new DeadEvent(this, event)); } dispatchQueuedEvents(); }
这里查找到参数匹配的EventHandler后并没有立刻执行反射调用,而是分发到了事件队列(ThreadLocal<Queue<EventWithHandler>> eventsToDispatch)中,当所有事件分发完毕之后,事件队列做统一的事件消费。
相关推荐
kururunga 2020-05-07
kururunga 2020-05-01
kururunga 2020-04-23
kururunga 2019-12-08
huangf 2015-04-17
kururunga 2015-05-17
Androidtalent 2019-09-08
kuangren 2019-04-23
kuangren 2017-05-09
kuangren 2019-06-30
游戏人日常 2019-06-28
dubuwucool 2019-06-27
kururunga 2019-06-26
游戏人日常 2019-06-25
kururunga 2020-11-16
pengruiyu 2020-08-01
kururunga 2020-07-16
一个来自吉尔尼斯 2020-04-21
一个来自吉尔尼斯 2020-04-10