RxJava2實現線程切換

閒談RxJava

  • RxJava:"a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫)
  • 異步。它其實就是一個實現異步操作的庫,基於觀察者模式,而且是鏈式調用的。

RxJava的三個基本元素

被觀察者(Observable)、觀察者(Observer)、訂閱(subscribe)。

1、創建被觀察者:
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(0);
        e.onNext(1);
        e.onNext(2);
        e.onComplete();
    }
});
2、創建被觀察者:
Observer observer = new Observer() {

        @Override
        public void onSubscribe(Disposable d) {}

        @Override
        public void onNext(Integer o) {}

        @Override
        public void onError(Throwable e) {}

        @Override
        public void onComplete() {}
    };
3、建立訂閱關係:
observable.subscribe(observer);

  • 被觀察者的創建常用三種:

    Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
                emitter.onNext(0);
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onComplete();
            });
    Observable.just(0);
    Observable.fromIterable(Arrays.asList(0,1, 2));

  • 觀察者的創建有兩種:

    Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {}

            @Override
            public void onNext(Integer o) {}

            @Override
            public void onError(Throwable e) {}

            @Override
            public void onComplete() {}
        };
    Consumer<Integer> consumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {}
        };

  • 訂閱關係有四種:

Disposable subscribe();
void subscribe(Observer<? super T> observer);
Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,Action onComplete, Consumer<? super Disposable> onSubscribe);
<E extends Observer<? super T>> E subscribeWith(E observer);

調度器Scheduler

  • Schedulers.computation():代表CPU計算密集型的操作, 例如需要大量計算的操作。
  • Schedulers.newThread():直接開啓一個新的線程。
  • Schedulers.io():開啓一個io線程,完成對網絡請求和文件讀寫數據庫增刪改查等操作。那io和newThread有什麼區別吶?newThread不管有沒有線程,他都會去重新開啓一個新的線程來進行操作,並且沒線程池維護。但是io的線程是無上限的,並且最大的一個好處是它會去重用空閒的線程,而不是每次都開啓一個線程來使用,效率上比newThread要高。所以,一般我們在使用的時候是直接使用io這個方法。
  • AndroidSchedulers.mainThread():android一個專門的線程,用來指定操作在主線程完成。

RxJava實現線程切換

subscribeOn():指定Observable被觀察者在哪個線程執行。要注意的是,如果多次調用此方法,只有第一次有效。
observeOn():指定Observe觀察者在哪個線程中執行。多次指定觀察者接收線程是可以的,每調用一次observerOn(),下游的線程就會切換一次。

  • 代碼探索:

    Observable.just(0)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",當前線程mainThread = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.io())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",當前線程io = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.newThread())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",當前線程newThread = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.computation())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",當前線程computation = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.single())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",當前線程single = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(AndroidSchedulers.mainThread())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",當前線程mainThread = " + Thread.currentThread().getName());
            return ++integer;
        })
        .subscribe();

  • log日誌:

    MyAppUtils: integer=0,當前線程mainThread = main
    MyAppUtils: integer=1,當前線程io = RxCachedThreadScheduler-3
    MyAppUtils: integer=2,當前線程newThread = RxNewThreadScheduler-1
    MyAppUtils: integer=3,當前線程computation = RxComputationThreadPool-1
    MyAppUtils: integer=4,當前線程single = RxSingleScheduler-1
    MyAppUtils: integer=5,當前線程mainThread = main

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