RxBus 代替 EventBus 進行組件之間通訊

▲ 前言

事件總線的好處在於方便組件之間的交互,RxBus不是一個庫,而是使用RxJava實現事件總線的一種思想。剛好項目中使用到了rxjava,相對於使用eventbus,使用rxbus來的更方便。

▲ rxbus和eventbus相比較

  • RxJava 主要做異步、網絡的數據處理,強大之處就是對數據的處理了,而對於處理完後的數據處理是一樣的都是觀察者模式來通知,也可以把 RxJava 進一步封裝出一個 EventBus(RxBus) 庫,二者可以轉換的。

  • EventBus比較適合僅僅當做組件間的通訊工具使用,主要用來傳遞消息。使用EventBus可以避免搞出一大推的interface,僅僅是爲了實現組件間的通訊,而不得不去實現那一推的接口

▲ rxbus實現原理

Note that it is important to subscribe to the exact same rxBus instance that was used to post the events

▲ 基本配置

    //引入rxJava
    compile 'io.reactivex.rxjava2:rxjava:2.1.8'
    //引入rxAndroid
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    //引入rxJava適配器,方便rxJava與retrofit的結合
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
    //引入J神的rxrelay2,出現異常仍然可以處理
    compile 'com.jakewharton.rxrelay2:rxrelay:2.0.0'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

▲ 基本使用 一

在訂閱者處理事件出現異常後,訂閱者無法再收到事件,這是 RxJava 當初本身的設計原則,但是在事件總線中這反而是個問題,不過 JakeWharton 大神寫了即使出現異常也不會終止訂閱關係的 RxRelay,所以基於 RxRelay 就能寫出有異常處理能力的 Rxbus。

/**
 * 有異常處理的 Rxbus
 * @author Donkor
 */

public class RxBus {
    private static volatile RxBus instance;
    private final Relay<Object> mBus;

    public RxBus() {
        this.mBus = PublishRelay.create().toSerialized();
    }

    public static RxBus getInstance() {
        if (instance == null) {
            synchronized (RxBus.class) {
                if (instance == null) {
                    instance = Holder.BUS;
                }
            }
        }
        return instance;
    }
    public void post(Object obj) {
        mBus.accept(obj);
    }

    public <T> Observable<T> toObservable(Class<T> tClass) {
        return  mBus.ofType(tClass);
    }

    public Observable<Object> toObservable() {
        return mBus;
    }

    public boolean hasObservers() {
        return mBus.hasObservers();
    }

    private static class Holder {
        private static final RxBus BUS = new RxBus();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

關於rxbus異常處理還不太瞭解的同學可以參考一下這篇文章:[深入RxBus]:異常處理

▲ 基本使用 二

沒有背壓處理(Backpressure)的 Rxbus

/**
 * @author Donkor
 */
public class RxBus {

    private final Subject<Object> mBus;

    private RxBus() {
        // toSerialized method made bus thread safe
        mBus = PublishSubject.create().toSerialized();
    }

    public static RxBus get() {
        return Holder.BUS;
    }

    public void post(Object obj) {
        mBus.onNext(obj);
    }

    public <T> Observable<T> toObservable(Class<T> tClass) {
        return mBus.ofType(tClass);
    }

    public Observable<Object> toObservable() {
        return mBus;
    }

    public boolean hasObservers() {
        return mBus.hasObservers();
    }

    private static class Holder {
        private static final RxBus BUS = new RxBus();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

有背壓處理(Backpressure)的 Rxbus

/**
 * @author Donkor
 */
public class RxBus {

    private final FlowableProcessor<Object> mBus;

    private RxBus() {
        // toSerialized method made bus thread safe
        mBus = PublishProcessor.create().toSerialized();
    }

    public static RxBus get() {
        return Holder.BUS;
    }

    public void post(Object obj) {
        mBus.onNext(obj);
    }

    public <T> Flowable<T> toFlowable(Class<T> tClass) {
        return mBus.ofType(tClass);
    }

    public Flowable<Object> toFlowable() {
        return mBus;
    }

    public boolean hasSubscribers() {
        return mBus.hasSubscribers();
    }

    private static class Holder {
        private static final RxBus BUS = new RxBus();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

關於有背壓與沒有背壓的知識介紹,可以參考下這一篇文章關於RxJava背壓

▲ 舉個栗子

場景:當前有三個(多個)activity,打開第二、三個(多個)activity需要修改第一個activity的數據時,這時就可以使用rxbus,相比發送廣播速度快。

無圖無真相,直接看下效果圖

第一個頁面關鍵代碼

RxBus.getInstance().toObservable().map(new Function<Object, EventMsg>() {
            @Override
            public EventMsg apply(Object o) throws Exception {
                return (EventMsg) o;
            }
        }).subscribe(new Consumer<EventMsg>() {
            @Override
            public void accept(EventMsg eventMsg) throws Exception {
                if (eventMsg != null) {
                    mTvContent.setText(eventMsg.getMsg());
                }
            }
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

第二個頁面關鍵代碼

                EventMsg eventMsg = new EventMsg();
                eventMsg.setMsg("來自第二個頁面發送過來的數據 --- 修改成功");
                RxBus.getInstance().post(eventMsg);
  • 1
  • 2
  • 3

EventMsg數據類

public class EventMsg {
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

▲ Demo下載地址https://download.csdn.net/download/donkor_/10312846

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章