Android消息傳遞之基於RxJava實現一個EventBus - RxBus

前言:

    上篇文章學習了Android事件總線管理開源框架EventBus,EventBus的出現大大下降了開發成本以及開發難度,今天咱們就利用目前大紅大紫的RxJava來實現一下相似EventBus事件總線管理,如今不少人都在說用這種方式來替代EventBus,今天咱們從開發效率,開發難度等維度來分析一下到底能不能取代EventBus? 先回顧一下什麼是EventBus?請看這篇文章Android消息傳遞之EventBus 3.0使用詳解(三)html

    消息傳遞相關文章地址:java

 需求:

      雖然軟件工程師就懼怕聽見「需求」這兩個字,可是一切功能來源於需求,咱們要基於RxJava實現一個publish/subscribe消息總線管理模型,這裏假設你已經知道如何使用RxJava了。下面看看如何實現。react

RxBus實現過程:

 1.)build.gradle中添加RxJava、RxAndroid引用

  compile 'io.reactivex:rxandroid:1.1.0'
  compile 'io.reactivex:rxjava:1.1.2'

2.)聲明一個管理事件總線的單例

public class RxBus {
    private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>();
    private static volatile RxBus instance;

    private RxBus() {
    }

    public static RxBus getInstance() {
        RxBus inst = instance;
        if (inst == null) {
            synchronized (RxBus.class) {
                inst = instance;
                if (inst == null) {
                    inst = new RxBus();
                    instance = inst;
                }
            }
        }
        return inst;
    }
}

考慮到RxBus單例頗有可能多線程併發訪問,這種存儲事件總線採用ConcurrentHashMapandroid

3.)訂閱者實現註冊/解除註冊方法

註冊/解註冊都以一個tag爲惟一標示,這裏採用的是事件的Class爲tag,來實現一個Event事件對象能夠對應多個訂閱者。編程

  /**
     * 註冊
     *
     * @param tag
     * @return
     */
    public <T> Observable<T> register(@NonNull Class<T> tag) {
        List<Subject> subjectList = subjectMapper.get(tag);
        if (null == subjectList) {
            subjectList = new ArrayList<>();
            subjectMapper.put(tag, subjectList);
        }
        Subject<T, T> subject = PublishSubject.create();
        subjectList.add(subject);
        return subject;
    }

    /**
     * 解除註冊
     *
     * @param tag
     */
    public <T> void unregister(@NonNull Class<T> tag, @NonNull Observable observable) {
        List<Subject> subjects = subjectMapper.get(tag);
        if (null != subjects) {
            subjects.remove(observable);
            if (subjects.isEmpty()) {
                subjectMapper.remove(tag);
            }
        }
    }

4.)實現發送消息、清除全部註冊

發送一個事件消息是經過獲取當前事件下的訂閱者列表,而後經過一個循環進行事件傳遞。至於事件運行在哪一個線程中由訂閱者決定。多線程

 /**
     * 發送消息
     *
     * @param event
     */
    public <T> void post(@NonNull Object event) {
        List<Subject> subjectList = subjectMapper.get(event.getClass());
        if (subjectList != null && !subjectList.isEmpty()) {
            for (Subject subject : subjectList) {
                subject.onNext(event);
            }
        }
    }

    /**
     * 清除訂閱
     */
    public void clear() {
        if (subjectMapper.isEmpty()) {
            return;
        }
        subjectMapper.clear();
    }

5.)如何使用

事件的訂閱者的註冊和清除全部註冊,訂閱者沒訂閱一個類型的事件都要返回一個Observable對象,這也是我的以爲比較頭疼的一件事,很難實現一個訂閱者對應多個事件類型,並且解註冊的時候也須要這些Observable對象進行一一解除。併發

    private Observable<DataSynEvent> observable;
    private void registerObservable() {
        observable = RxBus.getInstance().register(DataSynEvent.class);
        observable.observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<DataSynEvent>() {
            @Override
            public void call(DataSynEvent event) {
                Log.e(TAG, "event--2-->" + event.getCount());
            }
        });
    }

    private void unRegisterObservable() {
        if (observable != null) {
            RxBus.getInstance().unregister(DataSynEvent.class, observable);
        }
    }

事件的發送者發送事件,發送事件的處理還算比較友好,和EventBus很相似。app

  RxBus.getInstance().post(new DataSynEvent());

RxBus、EventBus 對比:

1.從引入依賴包對比框架

  RxBus 須要引入兩個包,EventBus須要引入一個,若是項目中沒有使用到RxJava編程的話,並不能減小包的依賴。ide

2 .從開發難度上對比

  上面也提到了實現RxBus是基於RxJava的,做爲一個新的編程方式函數式編程,對開發者的要求多多少少提升了那麼一點,並且每個訂閱都須要返回一個Observable,由訂閱者寫具體的代碼 須要執行在哪一個線程中,而EventBus 最新版本採用註解預編譯的方式,訂閱者註冊解註冊只需調用一個函數,並且經過註解的方式能夠標明事件的優先級,接收事件運行在哪一個線程,而且可以實現粘性事件,這些RxBus都須要進行二次開發。

3.)從開發效率上對比

   RxBus 須要進行大量的二次開發,不然只能實現簡單的事件傳遞,而EventBus只需簡單瞭解一下API就能上手。若是一個訂閱者須要註冊多個事件的時候,須要多個Observable全局變量,這不是瘋掉了嗎,而EventBus已經實現了一個訂閱者訂閱多個事件,和一個事件對應多個訂閱者。

4.)從功能完善上對比

    上面三個對比也說明了,EventBus實現了事件的優先級,訂閱事件運行的線程場景,以及粘性事件,這些在RxBus上面都須要進行二次實現。

總結:

    基於RxJava實現簡單的事件總線管理是能夠的,可是我的以爲想要取代EventBus不免有點說過頭了。因此若是項目中沒有使用RxJava的話 仍是採用EventBus比較靠譜。

相關文章
相關標籤/搜索