当前位置: 首页 > news >正文

EventBus源码主要流程解析

首先从最基本的EventBus类的register()看实现逻辑:

1. 订阅事件

通过一个SubscriberMethodFinder类查找对应订阅的方法,然后进行订阅。

public void register(Object subscriber) { if (AndroidDependenciesDetector.isAndroidSDKAvailable() && !AndroidDependenciesDetector.areAndroidComponentsAvailable()) { // Crash if the user (developer) has not imported the Android compatibility library. throw new RuntimeException("It looks like you are using EventBus on Android, " + "make sure to add the \"eventbus\" Android library to your dependencies."); } Class<?> subscriberClass = subscriber.getClass(); List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { for (SubscriberMethod subscriberMethod : subscriberMethods) { subscribe(subscriber, subscriberMethod); } } }

看下SubscriberMethodFinder类的findSubscriberMethods的实现。

可以看见实际上是通过Class进行反射,然后获取到对应的方法对象。

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) { List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass); if (subscriberMethods != null) { return subscriberMethods; } if (ignoreGeneratedIndex) { subscriberMethods = findUsingReflection(subscriberClass); } else { subscriberMethods = findUsingInfo(subscriberClass); } if (subscriberMethods.isEmpty()) { throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation"); } else { METHOD_CACHE.put(subscriberClass, subscriberMethods); return subscriberMethods; } } private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) { FindState findState = prepareFindState(); findState.initForSubscriber(subscriberClass); while (findState.clazz != null) { findUsingReflectionInSingleClass(findState); findState.moveToSuperclass(); } return getMethodsAndRelease(findState); } private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) { FindState findState = prepareFindState(); findState.initForSubscriber(subscriberClass); while (findState.clazz != null) { findState.subscriberInfo = getSubscriberInfo(findState); if (findState.subscriberInfo != null) { SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods(); for (SubscriberMethod subscriberMethod : array) { if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) { findState.subscriberMethods.add(subscriberMethod); } } } else { findUsingReflectionInSingleClass(findState); } findState.moveToSuperclass(); } return getMethodsAndRelease(findState); }

然后重新回到订阅方法,可以看到是把刚刚订阅超找到的方法和订阅者添加到CopyOnWriteArrayList中。并且还有个关键结构叫subscriptionsByEventType,这个容器包含了事件类型和订阅者,可以理解为EventType容器包含N个eventType的订阅队列,一个订阅队列中有多个订阅方法。

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { Class<?> eventType = subscriberMethod.eventType; Subscription newSubscription = new Subscription(subscriber, subscriberMethod); CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType); if (subscriptions == null) { subscriptions = new CopyOnWriteArrayList<>(); subscriptionsByEventType.put(eventType, subscriptions); } else { if (subscriptions.contains(newSubscription)) { throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event " + eventType); } } int size = subscriptions.size(); for (int i = 0; i <= size; i++) { if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) { subscriptions.add(i, newSubscription); break; } } List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber); if (subscribedEvents == null) { subscribedEvents = new ArrayList<>(); typesBySubscriber.put(subscriber, subscribedEvents); } subscribedEvents.add(eventType); if (subscriberMethod.sticky) { if (eventInheritance) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { Object stickyEvent = stickyEvents.get(eventType); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } }

2. 发送事件

这边可以看到先将事件提交到事件队列中,然后执行循环并取出队列第一个事件并执行postSingleEvent()。可以看见根据event的类去查找订阅的对象。

public void post(Object event) { PostingThreadState postingState = currentPostingThreadState.get(); List<Object> eventQueue = postingState.eventQueue; eventQueue.add(event); if (!postingState.isPosting) { postingState.isMainThread = isMainThread(); postingState.isPosting = true; if (postingState.canceled) { throw new EventBusException("Internal error. Abort state was not reset"); } try { while (!eventQueue.isEmpty()) { postSingleEvent(eventQueue.remove(0), postingState); } } finally { postingState.isPosting = false; postingState.isMainThread = false; } } } private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { Class<?> eventClass = event.getClass(); boolean subscriptionFound = false; if (eventInheritance) { List<Class<?>> eventTypes = lookupAllEventTypes(eventClass); int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } if (!subscriptionFound) { if (logNoSubscriberMessages) { logger.log(Level.FINE, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } }

最后可以看见将事件作为参数,对订阅者的订阅方法进行了反射调用,这样就实现了事件分发功能。

private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { CopyOnWriteArrayList<Subscription> subscriptions; synchronized (this) { subscriptions = subscriptionsByEventType.get(eventClass); } if (subscriptions != null && !subscriptions.isEmpty()) { for (Subscription subscription : subscriptions) { postingState.event = event; postingState.subscription = subscription; boolean aborted; try { postToSubscription(subscription, event, postingState.isMainThread); aborted = postingState.canceled; } finally { postingState.event = null; postingState.subscription = null; postingState.canceled = false; } if (aborted) { break; } } return true; } return false; } private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) { case POSTING: invokeSubscriber(subscription, event); break; case MAIN: if (isMainThread) { invokeSubscriber(subscription, event); } else { mainThreadPoster.enqueue(subscription, event); } break; case MAIN_ORDERED: if (mainThreadPoster != null) { mainThreadPoster.enqueue(subscription, event); } else { // temporary: technically not correct as poster not decoupled from subscriber invokeSubscriber(subscription, event); } break; case BACKGROUND: if (isMainThread) { backgroundPoster.enqueue(subscription, event); } else { invokeSubscriber(subscription, event); } break; case ASYNC: asyncPoster.enqueue(subscription, event); break; default: throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode); } }
http://www.cnnetsun.cn/news/55248.html

相关文章:

  • 33、资源描述框架(RDF):语义网的关键技术
  • 43、MathML:发展、应用与关键技术解析
  • 百度ERNIE 4.5大模型震撼发布:多模态技术突破与开源生态构建
  • Nintendo Switch全能工具箱:NSC_BUILDER深度解析与实战指南
  • 联想拯救者工具箱完整使用指南:从入门到精通的全流程解析
  • 终极指南:用开源贴片机实现专业级电子制造
  • 写小说卡文怎么办?2025全网10款AI写小说工具实测+保姆级创作攻略!(含避坑指南)
  • 推荐10款亲测有效的降ai率工具,含免费降ai率神器(收藏)
  • decimal.js高精度计算终极指南:彻底告别JavaScript精度丢失烦恼
  • 7、零售与电商:搭乘 AR/VR 技术的浪潮
  • 如何快速解决鸣潮卡顿问题:WaveTools终极解锁120帧指南
  • Visio + DeepSeek 联动:文本描述转流程图的标准化指令与格式优化
  • 旺玖PL27A1芯片,USB3.0数据对拷线方案,跨系统数据传输方案,PL27A1代理商
  • FF14智能自动跳过副本动画的高效解决方案
  • 基于SpringBoot + Vue的二手车交易平台
  • 基于SpringBoot + Vue的智能图书馆管理系统
  • 基于SpringBoot + Vue的智能交通信息发布平台的设计与实现
  • 旋转标定的数学公式
  • Linux系统编程1(文件操作、Makefile)
  • Zotero文献管理效率革命:Linter插件让你的文献库焕然一新
  • Free-NTFS-for-Mac终极指南:苹果电脑完美读写NTFS磁盘的完整解决方案
  • 卡牌批量生成终极指南:5分钟掌握桌游设计利器
  • 视频分段处理技术突破:多GPU协同下的超分辨率性能优化
  • DroidRun 革命性体验:用对话式命令玩转 Android 自动化
  • 25、寻找生成元和离散对数:算法与应用
  • 29、矩阵知识全解析:从基础定义到高斯消元法
  • 36、多项式算术及其应用
  • 37、多项式算术及其应用
  • Calibre-Douban插件:元数据管理与电子书整理的高效解决方案
  • 31、集群架构全解析:类型、配置与最佳实践