Android rxbus的構建使用

▲ 前言:

事件總線的好處在於方便組件之間的交互,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'

▲ 基本使用 一:

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

/**

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

public class RxBus {
private static volatile RxBus instance;
private final Relay 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();
}

}

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

▲ 基本使用 二:

沒有背壓處理(Backpressure)的 Rxbus

/**

  • @author Donkor
    */
    public class RxBus {

    private final Subject 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 Observable toObservable(Class tClass) {
    return mBus.ofType(tClass);
    }

    public Observable toObservable() {
    return mBus;
    }

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

    private static class Holder {
    private static final RxBus BUS = new RxBus();
    }
    }

有背壓處理(Backpressure)的 Rxbus

/**

  • @author Donkor
    */
    public class RxBus {

    private final FlowableProcessor 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 Flowable toFlowable(Class tClass) {
    return mBus.ofType(tClass);
    }

    public Flowable toFlowable() {
    return mBus;
    }

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

    private static class Holder {
    private static final RxBus BUS = new RxBus();
    }
    }

關於有背壓與沒有背壓的知識介紹,可以參考下這一篇文章關於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() {
@Override
public void accept(EventMsg eventMsg) throws Exception {
if (eventMsg != null) {
mTvContent.setText(eventMsg.getMsg());
}
}
});

第二個頁面關鍵代碼

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

EventMsg數據類

public class EventMsg {
private String msg;

public String getMsg() {
    return msg;
}

public void setMsg(String msg) {
    this.msg = msg;
}

}

轉載:https://blog.csdn.net/donkor_/article/details/79709366

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