天天看点

EventBus3.0优于Otto

两者都是主流的事件订阅框架,被广泛使用,两个框架,我都使用了一遍,并仔细阅读了源码,经过比较,建议大家以后使用EventBus3.0。

下面就来分析一下具体原因:

1、获取对象方式不同(非重要原因)

两者的构造方法都是public的,可以自由创建对象,但是通常情况,我们希望使用一个对象即可,所以会封装成单例的。

EventBus提供了单例的实现,通过EventBus.getDefault()获取。

而Otto的Bus类需要自己封装成单例。比如

public final class BusProvider {
  private static final Bus BUS = new Bus();

  public static Bus getInstance() {
    return BUS;
  }

  private BusProvider() {
    
  }
}
           

从设计方面来说,EventBus提供了更自由的控制,由EventBusBuilder来封装参数并创建对象,相信这种创建者模式大家在很多开源框架中

都见过了,比如Okhttp创建请求

Request request = new Request.Builder().url(url).build();
           

由Builder类来负责创建目标对象,以后扩展参数,就扩展Builder类即可,不用改动目标类。

这是EventBus的构造方法

public EventBus() {
	this(DEFAULT_BUILDER);
}

EventBus(EventBusBuilder builder) {
    //
}
           

以后要扩展参数,则扩展EventBusBuilder中的参数即可,不需要改动EventBus.

Bus的参数设置是通过构造方法注入的,以后如果需要扩展参数,则需要扩展Bus的构造方法,不是很方便。

public Bus() {
    this(DEFAULT_IDENTIFIER);
  }

  public Bus(String identifier) {
    this(ThreadEnforcer.MAIN, identifier);
  }

  public Bus(ThreadEnforcer enforcer) {
    this(enforcer, DEFAULT_IDENTIFIER);
  }

  public Bus(ThreadEnforcer enforcer, String identifier) {
    this(enforcer, identifier, HandlerFinder.ANNOTATED);
  }

  Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder) {
    this.enforcer =  enforcer;
    this.identifier = identifier;
    this.handlerFinder = handlerFinder;
  }
           

从设计方面上来说,我觉得EventBus3.0更好一点。

2、是否支持跨线程

EventBus支持订阅方法在不同线程中执行,通过@Subscribe的ThreadMode指定,由于支持跨线程,就可以很方便的替代类似Handler+Thread的异步交互方式。当子线程中的任务完成后,直接发送事件更新UI等。

Otto没有像EventBus那样强大实现了4种ThreadMode,Otto中在接口ThreadEnforcer提供了ANY和MAIN,在MAIN内部有一个是否是主线程的检查,而ANY不做任何检查的事情。因此Otto更多的使用场景是在主线程中,相对是轻量级的。

从这个实用功能来说,EventBus3.0又胜出一筹。当然两者都是不支持跨进程的。

3、订阅方法的继承支持

EventBus3.0查询订阅方法时,会从父类中查找,而Otto只会查找当前类中的订阅方法。

也就是说,在父类中定义的订阅方法,Otto是没法接收事件的。

public class BaseActivity extends Activity {
   
    @Subscribe
    public void onEvent(PushEvent pushEvent){
        System.out.println("onEvent-----"+pushEvent.getMsg());
    }
}
public class ChildActivity extends BaseActivity {

  
}
           

ChildActivity 继承 BaseActivity, 如果订阅事件定义在BaseActivity中,则EventBus3.0能接收到事件,而Otto不会。

4、订阅方法参数的限制

两者都支持事件的继承关系,比如事件类ChildEvent继承于FatherEvent,发送ChildEvent事件,则订阅了FatherEvent的方法也可以接收到。

EventBus3.0还支持接口,比如ChildEvent实现了接口EventInterface,发送ChildEvent事件,订阅了EventInterface的方法也可以接收到,而Otto是不支持接口的。

5、运行速度

两者都采用注解方式,但是EventBus3.0增加了索引加速,性能有大幅提升,这是一张性能对比图

EventBus3.0优于Otto

可以看出,EventBus3.0使用索引加速后,性能飙升了很多。

继续阅读