EventBus.

一、EvenntBus总结

1、注册

1)通过getDefault获得EvenntBus的单例,在这里面主要做了对象的初始化。主要是subscriptionsByEventType,这是map集合。key是eventType事件类型。

value是Subscription集合。Subscription是订阅信息对象,里面存储了 subscriber订阅者和SubscriberMethod。SubscriberMethod里面有method、threadMode、eventType、priority、sticky。

2)register方法,通过反射将订阅者类里面被@Subscribe注解的方法,解析为SubscriberMethod。然后存入到subscriptionsByEventType中。

2、发送事件

1)发送事件,将event添加到eventQueue事件队列中。然后while循环,取出事件队列的第一个事件。然后进行事件分发。

2)根据EventType从 subscriptionsByEventType 中取出对应的 subscriptions对象,遍历subscriptions获得subscription,然后调用postToSubscription() 方法

3)在postToSubscription,根据threadMode进行线程切换,最终调用invokeSubscriber方法。

4)在invokeSubscriber方法中,获取到subscription的subscriberMethod的method方法,然后通过反射调用。实现事件的传递。

3、解注册

移除subscriptionsByEventType和typesBySubscriber中Event 事件对应的订阅信息。

二、源码解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jbQtTlVs-1611411342287)(https://uploader.shimo.im/f/KQggjXxwM8erugvi.png!thumbnail?fileGuid=C6kVVDr33jwD6qYW)]

1、EventBus.getDefault().register

1、通过getDefault获得EvenntBus的单例,在这里面主要做了对象的初始化。

包括

2、register方法,将当前类注册的方法添加到

通过subscriberMethodFinder解析当前类下面的

1)EventBus.getDefault()

通过getDefault获得EvenntBus的单例,在这里面主要做了对象的初始化。

主要对如下几个对象进行初始化。

  • Map<Class<?>, CopyOnWriteArrayList> subscriptionsByEventType

key:是eventType事件类型。

value:是Subscription集合。Subscription是订阅信息对象,里面存储了 subscriber订阅者和订阅者类里面的被@Subscribe注解的SubscriberMethod。SubscriberMethod里面有method、threadMode、eventType、priority、sticky。

  • Map<Object, List<Class<?>>> typesBySubscriber

key:为subscriber对象,value:为subscriber对象中所有的EventType集合,日常使用中仅用于判断某个对象是否注册过。

  • Map<Class<?>, Object> stickyEvents;

它是专用于粘性事件处理的一个字段,key为事件的Class对象,value为当前的事件。

2)register

1、通过subscriberMethodFinder找到当前订阅者下面的订阅方法。

2、调用findUsingReflectionInSingleClass这个方法,通过反射的方式获取订阅者类中的所有声明方法,然后在这些方法里面寻找以 @Subscribe作为注解的方法。然后将method、eventType、threadMode,优先级,是否为 sticky 方法等信息封装到 SubscriberMethod 对象中,最后添加到 subscriberMethods 列表中。

3、遍历subscriberMethods,将subscriberMethod添加到subscriptionsByEventType

和typesBySubscriber中

public void register(Object subscriber) {
    Class<?> subscriberClass = subscriber.getClass();
    //通过反射的方式获取订阅者类中的所有声明方法,然后在这些方法里面寻找以 @Subscribe作为注解的方法进行处理,最后添加到 subscriberMethods 列表中。
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            subscribe(subscriber, subscriberMethod);
        }
    }
}

2、EventBus.getDefault().post(MessageEvent())

1)发送事件,将event添加到eventQueue事件队列中。然后while循环,取出事件队列的第一个事件。然后进行事件分发。

2)根据EventType从 subscriptionsByEventType 中取出对应的 subscriptions对象,遍历subscriptions获得subscription,然后调用postToSubscription() 方法

3)在postToSubscription,根据threadMode进行线程切换,最终调用invokeSubscriber方法。

4)在invokeSubscriber方法中,获取到subscription的subscriberMethod的method方法,然后通过反射调用。实现事件的传递。

5)ThreadMode解析:

  • POSTING:执行 invokeSubscriber() 方法,内部直接采用反射调用。
  • MAIN:首先去判断当前是否在 UI 线程,如果是的话则直接反射调用,否则调用mainThreadPoster的enqueue()方法,即把当前的方法加入到队列之中,然后通过 handler 去发送一个消息,在 handler 的 handleMessage 中去执行方法。
  • MAIN_ORDERED:与MAIN类型,不过是确保是顺序执行的。
  • BACKGROUND:判断当前是否在 UI 线程,如果不是的话直接反射调用,是的话通过backgroundPoster的enqueue()方法 将方法加入到后台的一个队列,最后通过线程池去执行。注意,backgroundPoster在 Executor的execute()方法 上添加了 synchronized关键字 并设立 了控制标记flag,保证任一时间只且仅能有一个任务会被线程池执行。
  • ASYNC:逻辑实现类似于BACKGROUND,将任务加入到后台的一个队列,最终由Eventbus 中的一个线程池去调用,这里的线程池与 BACKGROUND 逻辑中的线程池用的是同一个,即使用Executors的newCachedThreadPool()方法创建的线程池,它是一个有则用、无则创建、无数量上限的线程池。不同于backgroundPoster的保证任一时间只且仅能有一个任务会被线程池执行的特性,这里asyncPoster则是异步运行的,可以同时接收多个任务。

3、EventBus.getDefault().unregister(this)

移除subscriptionsByEventType和typesBySubscriber中Event 事件对应的订阅信息。

4、黏性事件

先将该事件放入 stickyEvents 中,然后调用post方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
eventbus.$on是Vue.js中的一个事件监听器方法。它用于注册一个事件监听器,使得我们可以监听特定事件的触发,并执行相应的回调函数。 当我们在Vue组件中使用eventbus.$on方法时,需要首先导入eventbus对象,一般我们可以在main.js中创建一个全局的eventbus实例。然后,我们可以在任何一个组件中使用eventbus.$on来注册事件的监听器。 使用eventbus.$on方法时,我们需要传入两个参数。第一个参数是要监听的事件名,这个事件名可以是一个字符串,也可以是一个常量。第二个参数是一个回调函数,用于接收事件触发时传递的数据,并进行相应的处理。 例如,我们可以在一个组件A中使用eventbus.$on方法来监听一个名为"customEvent"的事件: ``` import eventbus from '@/eventbus.js' export default { created() { eventbus.$on('customEvent', this.handleEvent) }, methods: { handleEvent(data) { // 处理事件触发后的逻辑 console.log(data) } }, beforeDestroy() { eventbus.$off('customEvent', this.handleEvent) } } ``` 在组件A的created钩子函数中,我们使用eventbus.$on方法注册了一个事件监听器,监听了"customEvent"事件,并指定了一个叫做handleEvent的回调函数来处理事件的触发。 在回调函数handleEvent中,我们可以获取到事件触发时传递的数据,进行相应的处理。这里我们使用console.log来打印出传递的数据。 当不再需要监听事件时,我们可以使用eventbus.$off方法来取消事件的监听。在组件A的beforeDestroy钩子函数中,我们使用eventbus.$off方法来取消"customEvent"事件的监听。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值