从源码角度再看EventBus 的使用

首先得明确EventBus是用来做什么的呢?

由greenrobot  组织贡献(该组织还贡献了greenDAO),一个Android事件发布/订阅轻量级框架

功能:通过解耦发布者和订阅者简化Android事件传递

EventBus可以代替Android传统的Intent,Handler,Broadcast或接口函数,在Fragment,Activity,Service线程之间传递数据,执行方法

特点:代码简洁,是一种发布订阅设计模式(观察者设计模式)。

 

 

先看简单的使用案例:

现要从MainActivity的生命周期onStart()方法中发送一条String类型的消息到SecondActivity,而此时SecondActivity尚未创建,我们如何将值从MainActivity传递到SecondActivity呢?看以下代码,就一目了然;

在MainActivity中

点击MainActivity中的按钮,跳转到SecondActivity

再看SecondActivity中对这条消息的处理

就这样,在SecondActivity未创建的时候,给它传值,SecondActivity依旧收的到;

我们带着问题,从源码的角度逐一分析;

第一步:注册

先看EventBus的注册:

 可以看到,这里是一个单例双重校验锁的实现,返回EventBus的实例

regiest方法中的参数是一个订阅者,也就是我们所说的Activity、Fragment

并由regiest中的参数,获取到订阅者的实例

并执行了   List<SubscriberMethod>subscriberMethods=subscriberMethodFinder.findSubscriberMethods(subscriberClass);

再看SubscriberMethodFinder的findSubscriberMethods方法

  • 如果有Map缓存中有值,就直接获取
  • 如果 ignoreGeneratedIndex为true 就 findUsingReflection(subscriberClass) 通过反射获取
  • 如果 ignoreGeneratedIndex为false ,就 findUsingInfo(subscriberClass) 获取
  • 最后
    • subscriberMethods 为空,内部报异常(对外是不会提示的)
    • subscriberMethods 不空,把对应的key为 subscriberClass, value为subscriberMethods 加入到 Map缓存中

而 subscribe(subscriber,subscriberMethod)方法又做了什么呢?看下面

 

 

 

第二步:取消事件订阅

取消订阅事件源码

第三步:发送消息或对象

postSticky(),发送一个粘性事件的消息,具体看源码

源码中的注释翻译如下:将给定的事件发布到事件总线并保持事件不变(因为它是粘性的)。事件类型的最新粘性事件保存在内存中,供订阅服务器使用{@link Subscribe#sticky()}进行未来访问。 

这也正好解释了最开始案例中MainActivity向尚未实例化的SecondActivity发了一条消息,而在SecondActivity实例化后,能接收到的缘故;

再看普通的Post()方法,将给定的事件发布到事件总线

第四步,接受发送过来的对象或message

ThreadMode的五种模式

POSTING

订阅者将在发布事件的同一线程中被直接调用。这是默认设置。事件交付意味着最少的开销,因为它完全避免了线程切换。因此,对于不需要主线程就可以在很短时间内完成的简单任务,这是推荐的模式。使用此模式的事件处理程序必须快速返回,以避免阻塞提交线程(可能是主线程)。

MAIN

在Android上,订阅者将在Android的主线程(UI线程)中被调用。如果发布线程是主线程,订阅者方法将被直接调用,从而阻塞发布线程。否则,事件将排队等待交付(非阻塞)。使用此模式的订阅服务器必须快速返回,以避免阻塞主线程。如果不在Android上,其行为与{@link # post}相同。

MAIN_ORDERED

在Android上,订阅者将在Android的主线程(UI线程)中被调用。与{@link #MAIN}不同的是,事件将始终排队等待交付。这确保了post调用是非阻塞的

BACKGROUND

在Android上,订阅者将在后台线程中被调用。如果发布线程不是主线程,订阅方方法将直接在发布线程中调用。如果发布线程是主线程,则EventBus使用单个后台线程,它将按顺序交付所有事件。使用此模式的订阅者应尝试快速返回,以避免阻塞后台线程。如果不是在Android上,总是使用一个后台线程

ASYNC

订阅服务器将在单独的线程中调用。这总是独立于发布线程和主线程。发布事件从不使用此模式等待订阅方方法。如果订阅者方法的执行可能需要一些时间,例如网络访问,则应使用此模式。避免同时触发大量长时间运行的异步订阅方方法来限制并发线程的数量。EventBus使用线程池来有效地重用来自已完成的异步订阅方通知的线程

磨刀不误砍柴工,弄明白这几种模式,也便于在开发过程中灵活使用;

 

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)注解方法中三个参数

1、ThreadMode 这个上面说了

2、stick  如果为真,则将最近的粘性事件(使用@link EventBus#postSticky(Object)}发布)传递给此订阅服务器(如果事件可用)。

3、priority   订阅者优先影响事件交付的顺序。在相同的提交线程中({@link ThreadMode}),高优先级的订阅者将比低优先级的订阅者更早收到事件。默认的优先级是0。注意:优先级不影响不同{@link ThreadMode}的订阅者之间的发送顺序!

今天就看这么多,希望闲来无事的大佬们,指点一二;

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值