天天看點

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使用索引加速後,性能飙升了很多。

繼續閱讀