【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));
            }
        }
    }
}
目录
相关文章
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
6天前
|
安全 Ubuntu Shell
深入解析 vsftpd 2.3.4 的笑脸漏洞及其检测方法
本文详细解析了 vsftpd 2.3.4 版本中的“笑脸漏洞”,该漏洞允许攻击者通过特定用户名和密码触发后门,获取远程代码执行权限。文章提供了漏洞概述、影响范围及一个 Python 脚本,用于检测目标服务器是否受此漏洞影响。通过连接至目标服务器并尝试登录特定用户名,脚本能够判断服务器是否存在该漏洞,并给出相应的警告信息。
118 84
|
5天前
|
存储 Java 开发者
浅析JVM方法解析、创建和链接
上一篇文章《你知道Java类是如何被加载的吗?》分析了HotSpot是如何加载Java类的,本文再来分析下Hotspot又是如何解析、创建和链接类方法的。
|
13天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
17天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
47 12
|
17天前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
44 3
|
1月前
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
48 12
|
1月前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
75 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
57 0

推荐镜像

更多