Android之EventBus

之前实习的时候就接触过这个框架,近来在弄模块化组件化的事情,感觉EventBus这个框架对于消除模块间依赖还是很有帮助的,顺便来整理一下。

大概的内容分为以下几个部分:

  • EventBus简介
  • 订阅者的注册/解注册源码分析
  • 事件的分发流程源码分析

EventBus简介

EventBus是设计模式中观察者(订阅者)模式的一种实现,为消除组件之间的耦合,实现组件之间的通信提供了一种很好的解决方案,成为一种通用的组件间通信框架。

在整个EventBus框架中,可以把组成成分分为四个部分:事件(Event),总线(EventBus),发布者(Publisher),订阅者(Subscriber)。他们之间的关系大致如图所示。

基本操作介绍

准备工作:在环境中配置依赖:

implementation 'org.greenrobot:eventbus:3.1.1'

在一般的实现中,我们所要做的分为三部分(这里直接拿官方文档内容):

  • 定义事件Event:
public static class MessageEvent { /* Additional fields if needed */ }
  • 定义事件的订阅者,并向EventBus进行注册:
//定义订阅者
@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MessageEvent event) {/* Do something */};


//注册
@Override
 public void onStart() {
     super.onStart();
     EventBus.getDefault().register(this);
 }

//解注册
 @Override
 public void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this);
 }
  • 发布事件:
 EventBus.getDefault().post(new MessageEvent());

五种线程模式

在EventBus中,一种定义了五种线程模式,这代表我们的订阅者可以在选择在这些线程中进行执行。这五种分别如下:

//默认线程,即订阅者处理事件的线程与发布者发布事件的线程相同
@Subscribe(threadMode = ThreadMode.POSTING)

//订阅者在主线程执行响应事件,如果发布者post事件的操作也在主线程,则直接执行
@Subscribe(threadMode = ThreadMode.MAIN)

//订阅者在主线程执行响应事件,区别在于不管如何(发布者post事件的操作是否处于主进程),订阅者都会把事件放入主线程队列中等待被执行
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)

//若发布者post事件的操作在主线程,则所有该模式的订阅者都在同一个子线程执行,若发布者post事件的操作所在线程为子线程,则就直接在该线程中处理
@Subscribe(threadMode = ThreadMode.BACKGROUND)

//订阅者会在一个独立的子线程中进行操作
@Subscribe(threadMode = ThreadMode.ASYNC)

Sticky事件

EventBus中还提供了sticky事件,这个事件的特点在于,一旦发布之后,如果有订阅者再次向EventBus注册订阅该事件,订阅者仍然能够接收到最近的一个sticky事件。其中相比于一般的事件,主要是在定义订阅者和发布事件这两步的操作有所区别:

  • 定义事件的订阅者:
//定义sticky事件
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(final StickyEvent event) {
    if (event.mMessage != null && event.mMessage.length() > 0) {
        Log.i(TAG, "onEvent: getMessage" + event.mMessage);
    }
}
  • 发布事件:
MessageEvent event = new MessageEvent("message");
EventBus.getDefault().postSticky(event);

另外,由于Sticky事件会将接收到的最新的event存储放在EventBus中,所以当我们不需要该事件时,应该将其移除掉,具体操作如下:

private void removeStickyEvent() {
    MessageEvent event = EventBus.getDefault().getStickyEvent(MessageEvent.class);
    if (event != null) {
        EventBus.getDefault().removeStickyEvent(event);
    }
}

编译时注解

在之前的EventBus中,当我们进行注册时,EventBus会通过反射的方式找到所有的订阅方法,这样存在的一个问题就是速度较慢。EventBus3中新增的一个特性,就是增加了编译时注解的功能,通过在编译时生成一个Index类,将所有的订阅者类以及其中所有的订阅方法放入到一个Map中,这样在注册的时候就可以通过这个Map找到所有的订阅者,从而加快执行速度。对于使用者来说,如果需要开启这个功能,所需要做的就是在build.gradle中添加如下内容:

defaultConfig {
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [ eventBusIndex : 'com.example.xyq.EventBusTestIndex' ]
        }
    }
}

dependencies {
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}

 

到此,EventBus的基本介绍就结束了,接下来对EventBus中的两个关键部分,订阅者的注册/解注册源码,以及事件的分发流程源码进行分析。

 

订阅者的注册/解注册源码分析

我们的注册是通过调用register()方法来实现的,该方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值