RxBus學習

學習資料

1. RxJava1.0版本使用

RxJava 2.0版本與1.0有些不同

1.1 RxBus簡單實現

主要用于發送接收

public class RxBus {
    private final Subject<Object, Object> bus;
    private static RxBus defaultRxBus;

    private RxBus() {
        bus = new SerializedSubject<>(PublishSubject.create());
    }

    public static RxBus getInstance() {
        if (null == defaultRxBus) {
            synchronized (RxBus.class) {
                if (null == defaultRxBus) {
                    defaultRxBus = new RxBus();
                }
            }
        }
        return defaultRxBus;
    }
    /*
     * 發送
     */
    public void post(Object o) {
        bus.onNext(o);
    }
    /*
     * 是否有Observable訂閱
     */
    public boolean hasObservable() {
        return bus.hasObservers();
    }
    /*
     * 轉換為特定類型的Obserbale
     */
    public <T> Observable<T> toObservable(Class<T> type) {
        return bus.ofType(type);
    }
}

post()方法就是使用onNext(Object o)方法,將Event對象發送出去

toObservable(Class<T> type),轉換為特定類型的Obserbale。方法內使用了ofType操作符,ofType源碼內就是filter + cast的組合,只發送特定的類型。fliter用來判斷是否為指定的類型,cast將一個Observable轉換為指定的特殊Observable


1.2 Activity中使用

最簡單的使用,只是為了使用而使用,沒有考慮任何場景

public class RxBusActivity extends AppCompatActivity {
    private CompositeSubscription mCom;
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx_bus);
        initView();
    }

    private void initView() {
        tv = (TextView) findViewById(R.id.rxbus_activity_tv);
        Button button = (Button) findViewById(R.id.rxbus_activity_send);
        //點擊發送事件
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RxBus.getInstance().post(new Event("RxBus Info!!!"));
            }
        });
        //接收
        mCom = new CompositeSubscription();
        //Event 類型的 Observable 訂閱
        Subscription subscription = RxBus.getInstance().toObservable(Event.class).subscribe(new Action1<Event>() {
            @Override
            public void call(Event event) {
                tv.setText(event.info);
            }
        });
        //將 Subscription 添加進 CompositeSubscription中
        mCom.add(subscription);    }

    class Event {
        String info;

        Event(String info) {
            this.info = info;
        }
    }
//    @Override
//    protected void onDestroy() {
//        super.onDestroy();
//        if (null != mCom && !mCom.isUnsubscribed()) {
//           mCom.unsubscribe();
//        }
//    }

}

Activity中有一個Button,點擊Button后發送一個攜帶字符串RxBus Info!!!Event對象

CompositeSubscription看作是用來收集Subscription容器,內部有一個new HashSet<Subscription>(4)


1.2.1 未取消訂閱發生內存泄漏

當成功接收到字符串信息后,點擊返回鍵,關閉當前使用了RxBus接收EventActivity,過了5秒鐘左右,使用的LeakCanary,便給出了內存泄漏信息

未取消訂閱,內存泄漏

原因:未取消訂閱

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mCom && !mCom.isUnsubscribed()) {
           mCom.unsubscribe();
        }
    }

記得在onDestory()取消訂閱,CompositeSubscription會將內部所有的Subscription取消訂閱


1.3 認識車零件

RxBus中涉及到3個重要零件

  • Subject

橋梁或者代理;既是Observable又是Observer。作為一個Observer,可以被一個或多個Observable進行subscribe訂閱;作為一個Observable,可以轉發收到(Observe)的數據,也可以發射新的數據


  • SerializedSubject

Subject 當作一個 Subscriber 使用時,注意不要從多個線程中調用它的onNext()方法,也包括其它的onXX()系列方法。這可能導致同時(非順序)調用,這會違反Observable協議,給Subject的結果增加了不確定性。需要將Subscriber轉換為一個SerializedSubject

mySafeSubject = new SerializedSubject( myUnsafeSubject )

  • PublishSubject

只會把在訂閱發生的時間點之后來自原始Observable的數據發送給Observer

PublishSubject可能會一創建完成,就開始發送數據。這可能會導致在Subject被創建到有觀察者訂閱它之前這個時間段內,有數據丟失。為了確保原始Observable的所有數據都被分發,可以使用PublishSubject.create(),以便手動給它引入冷Observable的行為,也就是當所有觀察者都已經訂閱時才開始發射數據


2. RxJava2.0版本

2.0版本的RxBus有些改動,但代碼實現思路應該還是一樣的。

RxJava1.0都只是了解一些基礎,2.0更不了解,需要再學習很長一段時間

2.1 RxBus2

代碼:

public class RxBus2 {
    private static RxBus2 defaultRxBus;
    private Subject<Object> bus;

    private RxBus2() {
        bus = PublishSubject.create().toSerialized();
    }

    public static RxBus2 getInstance() {
        if (null == defaultRxBus) {
            synchronized (RxBus2.class) {
                if (null == defaultRxBus) {
                    defaultRxBus = new RxBus2();
                }
            }
        }
        return defaultRxBus;
    }

    public void post(Object o){
        bus.onNext(o);
    }

    public boolean hasObservable() {
        return bus.hasObservers();
    }
    /*
     * 轉換為特定類型的Obserbale
     */
    public <T> Observable<T> toObservable(Class<T> type) {
        return bus.ofType(type);
    }
}

SerializedSubject不再通過直接new的方式,而是使用PublishSubject.create().toSerialized()的方式


2.2 Activity使用

代碼:

public class RxBus2Activity extends AppCompatActivity {
    private TextView textView;
    private CompositeDisposable compositeDisposable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx_bus2);
        initView();
    }

    private void initView() {
        textView = (TextView) findViewById(R.id.rx_activity_tv);
        Button button = (Button) findViewById(R.id.rx_activity_bt);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RxBus2.getInstance().post(new Event("RxBus2 Info!!!"));
            }
        });
        compositeDisposable = new CompositeDisposable();
        RxBus2.getInstance().toObservable(Event.class).subscribe(new Observer<Event>() {
            @Override
            public void onSubscribe(Disposable d) {
                compositeDisposable.add(d);
            }

            @Override
            public void onNext(Event event) {
                textView.setText(event.info);
            }

            @Override
            public void onError(Throwable e) {
                textView.setText(e.getMessage());
            }

            @Override
            public void onComplete() {

            }
        });
    }

    class Event {
        String info;

        Event(String info) {
            this.info = info;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != compositeDisposable && !compositeDisposable.isDisposed()) {
            compositeDisposable.clear();
        }
    }
}

subscribe()訂閱方法返回值為void,不再是Subscription。而取消訂閱的控制權則交給了
onSubscribe(Disposable d)方法中的Disposable。使用CompositeDisposable可以將所有的訂閱關系清除


3. 最后

過完年,第一篇博客,哈哈。看到朋友圈都在曬2017第一個工作日,作為一個沒有找到工作的人,表示各種羨慕

有錯誤,請指出

共勉 :)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容