EventBus源码---post流程分析

上篇文章我们说了register的流程,这篇呢我们来捋顺一下post流程是怎么工作的,其实post流程相对来说更为简单。当然这篇文章我们不说线程切换的问题,关于线程切换的问题,我们放在下片文章来说。

我们先看一下EventBus的post方法

    public void post(Object event) {
        //从ThreadLocal中拿到所属线程的PostingThreadState
        PostingThreadState postingState = currentPostingThreadState.get();
        //拿到事件队列
        List<Object> eventQueue = postingState.eventQueue;
        //把事件添加到队列中
        eventQueue.add(event);
        //判断是否出去发送状态
        if (!postingState.isPosting) {//如果不是发送状态,则进入循环
            //是否为主线程
            postingState.isMainThread = isMainThread();
            //修改PostingThreadState为发送状态
            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;
            }
        }
    }

所有的代码注释的很清楚,ThreadLocal隔离保存了每个线程的PostingThreadState,我们查看PostingThreadState源码可以知道,这个类保存了事件发送时的一些特征属性。具体的发送,我们查看postSingleEvent方法:

    private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
        //获取事件的class
        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));
            }
        }
    }

同样,相关的功能注释很清楚了。这里eventInheritance这个变量要注意一下,这个变量的含义:是否考虑事件的遗传问题。什么意思呢?我举一个例子:

比如A类实现了B接口,Test1Activity注册了EventBus,并且其中test方法被Subscribe注释,方法的参数为B类,Test2Activity中进行了post操作,事件类型为A。如果eventInheritance为true,那么test方法可以收到传递的事件

这个值是可以手动设置的,默认值是true。

具体的发送,需要再看postSingleEventForEventType方法:

    private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
        CopyOnWriteArrayList<Subscription> subscriptions;
        synchronized (this) {
            //根据事件class,拿到Subscription集合
            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;
    }

我们可以看到,通过eventClass拿到了Subscription集合,这个Subscription相信大家应该有印象,在register流程中提到过它,Subscription主要存储了注册类及方法的相关属性

之后就调用postToSubscription进行发送,我们看一下这个方法:

    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);
        }
    }

这里的代码进行了threadMode的判断,我们暂时不去看线程切换的功能,我们下片文章具体探究。无论是哪个threadMode,最终都会执行到invokeSubscriber这个方法,我们看这个方法:

    void invokeSubscriber(Subscription subscription, Object event) {
        try {
            subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
        } catch (InvocationTargetException e) {
            handleSubscriberException(subscription, event, e.getCause());
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Unexpected exception", e);
        }
    }

通过反射,对具体的观察方法进行了invoke,执行到了具体类的具体方法,这样就收到了相关的事件。

以上就是EventBus的post流程,有问题欢迎留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
abp-vnex eventbus是一个用于在ABP框架中进行事件通信的模块。要使用abp-vnex eventbus,您需要按照以下步骤进行安装和配置: 1. 首先,您需要安装abp-vnex eventbus模块。可以通过运行以下命令来安装: ```shell npm install abp-vnex-eventbus --save ``` 2. 安装完成后,您需要在您的应用程序的模块中导入abp-vnex eventbus模块。在您的模块文件中,添加以下代码: ```typescript import { AbpVnexEventBusModule } from 'abp-vnex-eventbus'; @NgModule({ imports: [ AbpVnexEventBusModule ] }) export class YourModule { } ``` 3. 现在,您可以在您的组件或服务中使用abp-vnex eventbus来发送和接收事件。首先,您需要导入`AbpVnexEventBusService`: ```typescript import { AbpVnexEventBusService } from 'abp-vnex-eventbus'; ``` 4. 在您的组件或服务中,您可以使用`AbpVnexEventBusService`的`emit`方法来发送事件。例如,发送一个名为`myEvent`的事件: ```typescript constructor(private eventBus: AbpVnexEventBusService) { } sendEvent() { this.eventBus.emit('myEvent', { data: 'Hello World' }); } ``` 5. 要接收事件,您可以使用`AbpVnexEventBusService`的`on`方法。在您的组件或服务中,添加以下代码: ```typescript constructor(private eventBus: AbpVnexEventBusService) { } ngOnInit() { this.eventBus.on('myEvent').subscribe((eventData) => { console.log(eventData.data); // 输出:Hello World }); } ``` 这样,您就可以使用abp-vnex eventbus模块来进行事件通信了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值