前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【EventBus】EventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )

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

作者头像
韩曙亮
发布2023-03-29 17:45:48
3200
发布2023-03-29 17:45:48
举报

文章目录

一、EventBus 事件发送


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

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

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

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

EventBus.post 方法源码 :

代码语言:javascript
复制
/**
 * 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 方法


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

代码语言:javascript
复制
    	// 获取发送的消息事件类型 
        Class<?> eventClass = event.getClass();

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

代码语言:javascript
复制
        // 判断事件类型的父类 , 向事件的上一级类型查找 
        //		传入的是否是某个事件的父类对象 
        //		该值默认为 true 
        if (eventInheritance) {

如果支持事件类型父类查找 , 则获取当前所有的事件类型集合 , 进行单个事件的发送 ;

代码语言:javascript
复制
        	// 获取当前所有的 事件类型 集合 
            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 方法源码 :

代码语言:javascript
复制
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));
            }
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-09-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、EventBus 事件发送
  • 二、事件发送 postSingleEvent 方法
相关产品与服务
事件总线
腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档