【EventBus】EventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 【EventBus】EventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )

文章目录

一、EventBus 事件发送

二、事件发送 postSingleEvent 方法





一、EventBus 事件发送


在客户端的某个线程中 , 调用 EventBus.getDefault().post("Hello EventBus !"); 方法 , 向消息中心发送消息 ;


在 EventBus 中 , 获取 ThreadLocal 数据 PostingThreadState , 其中记录了 线程状态信息 , 其中维护了一个事件队列 List<Object> eventQueue , 将本次传入的事件 , 加入到该事件队列中 ;


然后判断发布线程是否是主线程 , 并保存发送状态 ;


     

// 判断是否处于主线程 
            postingState.isMainThread = isMainThread();
            // 保存临时状态 , 放置重复调用 
            postingState.isPosting = true;



EventBus.post 方法源码 :


/**
 * EventBus是Java和Android的中央发布/订阅事件系统。
 * 事件被发布({@link#post(Object)})到总线,总线将其传递给具有匹配处理程序的订阅者
 * 事件类型的方法。
 * 要接收事件,订阅者必须使用{@link#register(Object)}将自己注册到总线。
 * 一旦注册,订阅服务器将接收事件,直到调用{@link#unregister(Object)}。
 * 事件处理方法必须由{@link Subscribe}注释,必须是公共的,不返回任何内容(void),
 * 并且只有一个参数(事件)。
 */
public class EventBus {
    private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
        @Override
        protected PostingThreadState initialValue() {
            return new PostingThreadState();
        }
    };
    /** 将给定的事件传递给事件总线 */
    public void post(Object event) {
      // ThreadLocal 数据
      //  ThreadLocal<PostingThreadState> currentPostingThreadState
      // PostingThreadState 可以理解成一个辅助类
        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;
            }
        }
    }
}






二、事件发送 postSingleEvent 方法


首先 , 获取发送的事件类型 ;


 

// 获取发送的消息事件类型 
        Class<?> eventClass = event.getClass();


然后通过 eventInheritance 变量 , 判断是否支持事件类型的父类查找 , 该值默认为 true ;


       // 判断事件类型的父类 , 向事件的上一级类型查找

// 判断事件类型的父类 , 向事件的上一级类型查找 
        //  传入的是否是某个事件的父类对象 
        //  该值默认为 true 
        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);
            }



EventBus.postSingleEvent 方法源码 :


public class EventBus {
    private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
      // 获取发送的消息事件类型 
        Class<?> eventClass = event.getClass();
        boolean subscriptionFound = false;
        // 判断事件类型的父类 , 向事件的上一级类型查找 
        //  传入的是否是某个事件的父类对象 
        //  该值默认为 true 
        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));
            }
        }
    }
}
目录
相关文章
|
14天前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
65 29
|
15天前
|
JSON 监控 网络协议
Bilibili直播信息流:连接方法与数据解析
本文详细介绍了自行实现B站直播WebSocket连接的完整流程。解析了基于WebSocket的应用层协议结构,涵盖认证包构建、心跳机制维护及数据包解析步骤,为开发者定制直播数据监控提供了完整技术方案。
|
9天前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
20 1
|
11天前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
29 3
|
13天前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
23天前
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。
|
13天前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
21天前
|
存储 前端开发 JavaScript
在线教育网课系统源码开发指南:功能设计与技术实现深度解析
在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。
|
4月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
153 2
|
1月前
|
机器学习/深度学习 自然语言处理 算法
生成式 AI 大语言模型(LLMs)核心算法及源码解析:预训练篇
生成式 AI 大语言模型(LLMs)核心算法及源码解析:预训练篇
146 0

热门文章

最新文章

推荐镜像

更多