当前位置:   article > 正文

EventBus 利弊与源码解析_java eventbus的优缺点

java eventbus的优缺点

原文连接, 转载请注明作者和原文连接(@woaitqs
,woaitqs.github.io)

EventBus 需要解决的问题

在日常编码里面,我们会遇到很多网络请求,数据库操作等等,一般情况下这些操作都是通过观察者模式来实现的。通过Volley来简单举个例子:

ImageRequest request = new ImageRequest(url,
    new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap bitmap) {
            mImageView.setImageBitmap(bitmap);
        }
    }, 0, 0, null,
    new Response.ErrorListener() {
        public void onErrorResponse(VolleyError error) {
            mImageView.setImageResource(R.drawable.image_load_error);
        }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

此时,你会发现并且开始思考一个问题,如果很多观察者模式需要使用了? 比如,你正在开发一个东西,需要监听网络状态变化,App的安装情况,内容的下载情况。当存在很多观察者模式,「如何将这些事件通知到监听者」是可以复用的模块,这就是EventBus存在的意义。这里需要大家想明白一个问题,观察者模式本身就是一个可以复用的模块。

  • 内容下载模块
  • 电量监听模块
  • App按照通知

他们都可以通过EventBus将自身的事件发布出去,使用者只需要在这个模块里面,注册对于自己感兴趣的内容就行。

EventBus 发布和接收模块

EventBus 带来的好处和引入的问题

好处比较明显,就是独立出一个发布订阅模块,调用者可以通过使用这个模块,屏蔽一些线程切换问题,简单地实现发布订阅功能。

坏处可能比较隐晦,但这些需要足够引起我们的重视

  • 大量的滥用,将导致逻辑的分散,出现问题后很难定位。
  • 没办法实现强类型,在编译的时候就发现问题,(Otto实现了这个,但性能有问题)。在实现上通过一个很弱的协议,比如onEvent{XXX}, {XXX}表示ThreadModel,来实现线程的切换。后面在代码解析的时候,会说明这个问题。
  • 代码可读性有些问题,IDE无法识别这些协议,对IDE不友好。

总得来说,如果项目里面有大量的事件交互,那么还是可以通过EventBus来实现,否则还是推荐自己在模块内部实现观察者模式

EventBus 源码解析

EventBus.java

源码阅读从外观类开始,这里是 EventBus.java,核心接口都在这个类里面实现,对内容感兴趣的调用方使用 register 方法,当有事件产生的时候,会在onEvent的时候收到相应的回调。

register(Object object);

registerSticky(Object object);

unRegister(Object object);

post(Object object);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

先看看初始化部分,看看如何实现单例的(可选的)。

// volatile 这里是需要重视的,这个关键字保证了defaultInstance在不同线程间的可见性,也就是说在多线程环境下,看到的仍然是最新修改的值。
static volatile EventBus defaultInstance;
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
    // 这一步不存在线程问题,volatile保证了。如果没有defaultInstance实例化出来,
    if (defaultInstance == null) {
        synchronized (EventBus.class) {
            // 进入同步块的时候,不能保证defaultInstance没有被实例化出来,所以需要进行double-check
            if (defaultInstance == null) {
                defaultInstance = new EventBus();
            }
        }
    }
    return defaultInstance;
}

// 这里实现的时候,考虑的是defaultInstance 不一定是每个人都需要创建的,否则没必要使用lazy的实现方式
// 下面是一种实现方式
static {
    defaultInstance = new EventBus();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

EventBus实现了EventBusBuilder,通过Builder的方式使得构建的时候更加容易

public static EventBusBuilder builder() {
    return new EventBusBuilder();
}
  • 1
  • 2
  • 3

下面重点看看register(Object subscriber, boolean sticky, int priority)方法

private synchronized 
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/251176
推荐阅读
相关标签
  

闽ICP备14008679号