Android EventBus粘性事件实现机制探究

 更新时间:2022年05月31日 09:27:55   作者:长安皈故里  
最近项目做组件化,需要进行组件化的通信,有时候可能会出现异步的情况,事件接收方还没准备好事件就已经发送过来了,这时候想到了EventBus的粘性事件,这篇文章主要给大家介绍了关于Android EventBus粘性事件实现机制的相关资料,需要的朋友可以参考下

众所周知,EventBus是支持粘性事件的,即可以先发送粘性事件,然后再注册,代码如下:

  • 粘性事件观察者
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun registerEventBus(o: Any) {    
}
  • 发送粘性事件
EventBus.getDefault().postSticky(Any())
  • 注册EventBus
EventBus.getDefault().register(this)

接下来我们就来探究下EventBus的粘性事件是如何实现的。

postSticky()内部机制

  • 如果是发送的粘性事件,会添加到stickyEvents中,看下这个属性的实现:

可以看到这个属性是一个Map集合,其中key为事件类型的class对象,value为对应的事件类型。

  • 继续看下post(Event)方法:

  • 首先将这个粘性事件添加到PostingThreadState(线程私有)的eventQueue集合中

  • 通过isMainThread方法判断当前是否为主线程,最终会调用到我们熟悉的Looper.getMainLooper() == Looper.myLooper()进行判断

  • 循环遍历eventQueue队列,不断的取出集合元素进行分发,看下postSinleEvent()方法如何实现:

  • 如果eventInheritance为true,会查找当前发送的粘性事件类型的父类型,并返回查找到的集合

  • 接下来就会调用postSingleEventForEventType()方法来进行最终粘性事件的分发,即通知通过@Subscribe注解注册的粘性事件观察者,看下具体实现:

  • 调用subscriptionsByEventType获取注册该事件类型的所有订阅方法,但是由于这个时候我们是先发送的粘性事件再注册EventBus,而subscriptionsByEventType中集合元素的填充实在注册EventBus发生的,所以通过subscriptionsByEventType获取到的subscriptions将是null的,所以接下来肯定不会走下面的if代码块中的逻辑了。

postSticky()小结

上面这么多代码逻辑,其实只干了一件事,就是将这个粘性事件添加到了stickyEvents这个集合中。之后的逻辑虽多,但和粘性事件没啥关系。

register内部机制

  • findSubscriberMethods()这个方法里面的逻辑就不带大家进行分析了,总之就干了一件事情:

查找当前类通过@Subscribe注册的所有事件订阅方法,并返回一个List<SubscriberMethod>集合,其中SubscriberMethod就是对每个注册的订阅方法和当前注册类的封装

  • subscribe这个方法是关键,深入探究下:

  • 第1、2、3、4步中其实就干了两件事情:

    • 填充subscriptionsByEventType集合,key为事件类型,value为通过@Subscribe订阅了该事件类型的方法集合
    • 填充typesBySubscriber集合,key为注册EventBus的类,value为该类中所有@Subscribe注解修饰的方法集合
  • 第5步就是实现粘性事件分发的关键地方

    • 首先判断当前@Subscribe修饰的订阅方法是否为粘性,即@Subscribe(sticky = true)sticky等于true
    • 是的话就从stickyEvents集合中判断是否存在和订阅方法中注册的事件类型相同的事件:

    这个stickyEvents是不是很熟悉,就是我们之前发送粘性事件时,将粘性事件添加到的方法集合

    • 如果存在,则就执行该粘性事件的分发,即调用执行该订阅方法,最终会调用到invokeSubscriber()方法:

从上面可以看到,最终是通过反射来实现的订阅了粘性事件方法的执行。

register小结

该方法最终会判断当前是否存在注册EventBus前发送的粘性事件,且当前注册类中存在订阅该事件类型的方法,然后立即执行。

总结

以上就是EventBus粘性事件的内部实现机制,总体来说不算复杂,大家看着文章跟着源码一步步分析应该就很容易理解这部分实现逻辑了。

到此这篇关于Android EventBus粘性事件实现机制的文章就介绍到这了,更多相关Android EventBus粘性事件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android实现页面跳转的全过程记录

    Android实现页面跳转的全过程记录

    对于android软件开发初级学习者来说,简单的页面跳转是必学的,这篇文章主要给大家介绍了关于Android实现页面跳转的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-10-10
  • 详解Flutter WebView与JS互相调用简易指南

    详解Flutter WebView与JS互相调用简易指南

    这篇文章主要介绍了详解Flutter WebView与JS互相调用简易指南,分为JS调用Flutter和Flutter调用JS,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • Android 8.0实现发送通知

    Android 8.0实现发送通知

    这篇文章主要为大家详细介绍了Android 8.0实现发送通知,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • FFmpeg Principle学习new_video_stream添加视频输出流

    FFmpeg Principle学习new_video_stream添加视频输出流

    这篇文章主要为大家介绍了FFmpeg Principle学习new_video_stream添加视频输出流示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Android修改自己程序字体的方法详解

    Android修改自己程序字体的方法详解

    本篇文章是对Android修改自己程序字体的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • Kotlin入门教程之开发环境搭建

    Kotlin入门教程之开发环境搭建

    最近kotlin大热,Kotlin作为 Android 领域的 Swift,绝对让你如沐春风,下面这篇文章主要给大家介绍了关于Kotlin入门教程之开发环境搭建的相关资料,文中将实现的方法一步步介绍的非常详细,需要的朋友可以参考下。
    2017-10-10
  • Android自定义流式布局/自动换行布局实例

    Android自定义流式布局/自动换行布局实例

    这篇文章主要介绍了Android自定义流式布局/自动换行布局实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • android自定义窗口标题示例分享

    android自定义窗口标题示例分享

    这篇文章主要介绍了android自定义窗口标题示例,需要的朋友可以参考下
    2014-03-03
  • Android实现聊天界面

    Android实现聊天界面

    这篇文章主要为大家详细介绍了Android实现聊天界面的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • Android开发获取手机Mac地址适配所有Android版本

    Android开发获取手机Mac地址适配所有Android版本

    这篇文章主要介绍了Android开发获取手机Mac地址适配所有Android版本,需要的朋友可以参考下
    2020-03-03

最新评论