无冥冥之志者,无昭昭之明;无惛惛之事者,无赫赫之功。
解释:没有专心致志地刻苦学习,就没有融会贯通的智慧;没有埋头执着的工作,就不会取得显著的成就。
EventBus使用及原理
学习一个第三方库,从几方面入手:
- 是什么?
- 干什么用的(功能是什么)?
- 与现有技术比较,怎么样?
- 怎么用?
EventBus是什么?
EventBus,一个Android事件发布/订阅的框架。通过解耦发布者和订阅者,简化Android事件传递。
干什么用的(功能是什么)?
EventBus主要的功能就是事件的传递。那可以在什么之间传递事件呢?Activity之间、Service之间、Fragment之间,或者线程之间传递事件。
与现有技术比较,怎么样?
现有的事件传递方法:Intent、Handler、BroadCastReceiver,Interface。相比之下,EventBus开销小,代码简洁,使用简单,事件发布与订阅充分解耦。
怎么用?
步骤如下:
- 创建事件类:该类可以随意命名,不过根据代码规范应该带生Event字眼。
- 注册事件接收者:在需要处理事件的类调用:Eventbus.getDefault().register()
- 写接收事件的方法:在注册事件的类中定义接收事件方法,事件接收方法需要使用@Subscribe注释,EventBus3.0可以随意命名,但是EventBus2.0需要按照命名约定来命名。@Subscribe中需要设置参数,以规定接收到的事件在哪个进程中处理。参数可以设置:
- ThradMode:POSTING:默认的线程模式,如果指定线程模型是这个,那么事件在哪个线程发出来,事件的处理就会在这个线程中运行。这种模型中的事件处理应该避免耗时操作。因为事件的分发和处理都在一个线程,所以多事件分发的时候,可能会导致线程阻塞。
- ThreadMode:MAIN:这中线程模型中,接收到事件之后,会在主线程中进行事件的处理。如果事件发布就是在主线程,则直接调用事件接收方法,如果不是主线程中发出的事件,那么会使用主线程的Handler发送消息切换到主线程,显然,这种线程模型也不能进行耗时操作。
- ThreadMode:BACKGROUND:在后台线程中处理事件。如果事件发出的线程不是主线程,那么直接在发出事件的线程中处理,如果是在主线程发出的,那么会创建一个唯一的后台线程进行事件处理。因为事件多的时候,只有一个线程进行事件分发和处理,可能造成阻塞,所以太耗时的任务不适合在此类型中进行。
- ThreadMode:ASYNC:无论事件在哪个线程发出,事件的处理都会从线程池中拿出一个子线程中进行,所以这种线程模型可以进行耗时任务,但是不能更新UI操作。
- 发送事件:在需要发送事件的地方调用:EventBus。getDefalult().post(事件类对象)
- 取消注册事件:在注册事件的类中调用: EventBus.getDefalut().unregister();
5、原理是什么?
a、EventBus中使用两个集合来记录事件与事件订阅者之间的关系: subscriptionBy EventType: 集合记录订阅者订阅来哪些事件。 typeBySubscriber:记录一个事件被哪些订阅者订阅。
b、register:注册事件接收的时候,会使用发射技术,查找当前类有哪些方法是使用@Subscribe注释的,找到这些方法进行验证,判断是不是EventBus的事件接收方法,是的话,就根据参数threadMode的值,确定事件的处理在哪个线程进行,然后把订阅关系存到subscriptionByEventType和typeBySubscriber。
c、post:post方法接收一个事件,然后遍历subscriptionByEventType,找到订阅类这个事件的所有订阅者,调用它们的事件处理方法。 d、取消注册:当一个类调用EventBus.getDefault().unregister()的时候,从typeBySubscriber中找到这个类对应的订阅者,remove掉。
内部原理有哪些设计的好的地方?
对象池,FindState对象池,对象重用
有没有其他实现方式?
RxJava可以实现