1. 程式人生 > >小白裝逼:使用rxjava代替eventBus

小白裝逼:使用rxjava代替eventBus

接著之前說的rxjava代替eventBus的,現在大部分的專案都有使用retrofit+rxjava,所以為了方便,直接使用rxjava來代替eventbus事件匯流排.雖然這樣有些不足的地方,但也是一個不錯的方案….

匯入包

    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'

或者

  compile 'io.reactivex.rxjava2:rxjava:2.0.1'
  compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

配置

public class RxBus {
    private static volatile RxBus mDefaultInstance;//單例
    private final Subject<Object, Object> mBus;

    private final Map<Class<?>, Object> mStickyEventMap;//這裡是為了給每一類事件做標記

    public RxBus() {
        mBus = new SerializedSubject<>(PublishSubject.create());//使用publishSubject(可以先訂閱後出發其onNext等方法的subJect)建立一個執行緒安全的SerializedSubject
mStickyEventMap = new ConcurrentHashMap<>();//這裡使用執行緒安全的map } public static RxBus getDefault() {//獲取單例 if (mDefaultInstance == null) { synchronized (RxBus.class) { if (mDefaultInstance == null) { mDefaultInstance = new RxBus(); } } } return
mDefaultInstance; } /** * 傳送事件 */ public void post(Object event) { mBus.onNext(event); } /** * 傳送一個新Sticky事件 */ public void postSticky(Object event) { synchronized (mStickyEventMap) { mStickyEventMap.put(event.getClass(), event); } post(event); } /** * 判斷是否有訂閱者 */ public boolean hasObservers() { return mBus.hasObservers(); } /** * 重新設定訂閱者 */ public void reset() { mDefaultInstance = null; } /** * 根據傳遞的 eventType 型別返回特定型別(eventType)的 被觀察者 */ public <T> Observable<T> toObservable(Class<T> eventType) { return mBus.ofType(eventType); } /** * 根據傳遞的 eventType 型別返回特定型別(eventType)的 被觀察者 */ public <T> Observable<T> toObservableSticky(final Class<T> eventType) { synchronized (mStickyEventMap) { Observable<T> observable = mBus.ofType(eventType);//獲取釋出者(被觀察者)的Observable final Object event = mStickyEventMap.get(eventType);//獲取儲存的eventType事件型別 if (event != null) { return observable.mergeWith(Observable.just(eventType.cast(event))); //mergeWith是結合倆個observable,just是將內容原樣發射,cast為強制轉換為當前型別; // 綜合為:獲取原事件匯流排的事件並將新的與其結合後一同放入事件匯流排 } else { return observable; } } } /** * 根據eventType獲取Sticky事件 */ public <T> T getStickyEvent(Class<T> eventType) { synchronized (mStickyEventMap) { return eventType.cast(mStickyEventMap.get(eventType)); } } /** * 移除指定eventType的Sticky事件 */ public <T> T removeStickyEvent(Class<T> eventType) { synchronized (mStickyEventMap) { return eventType.cast(mStickyEventMap.remove(eventType)); } } /** * 移除所有的Sticky事件 */ public void removeAllStickyEvents() { synchronized (mStickyEventMap) { mStickyEventMap.clear(); } } }

建立一個統一事件型別類(一個用於儲存傳遞資料的類,這裡只儲存一個字串,可以傳遞更多資訊)

public class EventSticky {
    public String event;

    public EventSticky(String event) {
        this.event = event;
    }

    @Override
    public String toString() {
        return "EventSticky{" +
                "event='" + event + '\'' +
                '}';
    }
}

rxjava的使用

這裡的使用方式有兩種:
1.直接使用post/toObservable,這方式在管理訂閱者上有些不好,若使用此方式,可以將RxBus中Sticky的程式碼刪除;;
2.使用postSticky/toObservableSticky,這方式在上述程式碼中有對訂閱者的管理(推薦);;

(方式1與2基本一樣,只是呼叫方法和取消訂閱不同)

訂閱事件

private Subscription mRxSubSticky;//這裡使用Subscription 來管理訂閱者

private void subscribeEventSticky() {
                if (mRxSubSticky != null && !mRxSubSticky.isUnsubscribed()) {
                        RxSubscriptions.remove(mRxSubSticky);//這裡為解除訂閱者
                } else {
                        EventSticky s = RxBus.getDefault().getStickyEvent(EventSticky.class);//這裡是測試獲取到的事件
                        Log.i("FFF", "獲取到StickyEvent--->" + s);

                        mRxSubSticky = RxBus.getDefault().toObservableSticky(EventSticky.class)
                                .subscribe(new RxBusSubscriber<EventSticky>() {
                                        @Override
                                        protected void onEvent(EventSticky eventSticky) {
                                                Log.e("FFF", "onNext--Sticky-->" + eventSticky.event);
                                            if("img_head".equals(eventSticky.event)){
                                                Log.w("---rxtest---",eventSticky.event);
                                            }
                                                if("getNewOrder".equals(eventSticky.event)){
                                                      Log.i("---接收發來的事件---",eventSticky.event);
                                                }
                                                if ("doneOrder".equals(eventSticky.event)){
                                                      Log.i("---接收發來的事件---",eventSticky.event);
                                                }
                                                if ("order".equals(eventSticky.event)){
                                                      Log.i("---接收發來的事件---",eventSticky.event);

                                                }
                                                if("img_head".equals(eventSticky.event)){

                                                }


                                        }
                                });
                        RxSubscriptions.add(mRxSubSticky);

                }
        }

發起事件

 RxBus.getDefault().postSticky(new EventSticky("getNewOrder"));

解除訂閱

RxSubscriptions.remove(mRxSubSticky);
RxBus.getDefault().removeAllStickyEvents();

結尾吐槽

以上是本人專案中接觸到的rxjava代替eventBus的方法,就是在訂閱事件的時候,處理的多一些,其他的還是很好用的.和eventBus比較的話,rxjava適用於一個訂閱者訂閱一個事件,因為如果要訂閱多個事件的話就要註冊多次,而eventBus直接實現一個訂閱者訂閱多個事件…..

以上內容,純屬個人理解,如有錯誤,請指出糾正,若有雷同,你肯定在做夢~~~~