Rxjava2 Observable的輔助操作詳解及實(shí)例(一)

簡要:

需求了解:

Rxjava中有一些方便的輔助操作符,來更方便我們的函數(shù)式的編程。比如延遲、定時(shí)、指定操作的監(jiān)聽、數(shù)據(jù)類型轉(zhuǎn)換等一系列的操作。

下面列出了一些用于Observable的輔助操作符:

  • Delay:延時(shí)發(fā)射Observable的結(jié)果。
  • Do:注冊一個(gè)動(dòng)作作為原始Observable生命周期事件的監(jiān)聽器。
  • SubscribeOn:指定Observable自身在哪個(gè)調(diào)度器上執(zhí)行。
  • ObserverOn:指定一個(gè)觀察者在哪個(gè)調(diào)度器上觀察這個(gè)Observable。
  • Serialize:強(qiáng)制一個(gè)Observable連續(xù)調(diào)用并保證行為正確,其實(shí)就是同步事件操作。
  • Materialize/Dematerialize:將數(shù)據(jù)項(xiàng)和事件通知都當(dāng)做數(shù)據(jù)項(xiàng)發(fā)射 ,Dematerialize 剛好相反。
  • TimeInterval:將一個(gè)發(fā)射數(shù)據(jù)的Observable轉(zhuǎn)換為發(fā)射那些數(shù)據(jù)發(fā)射時(shí)間間隔的Observable。
  • Timeout:對原始Observable的一個(gè)鏡像,如果過了一個(gè)指定的時(shí)長仍沒有發(fā)射數(shù)據(jù),它會發(fā)一個(gè)錯(cuò)誤通知。
  • Timestamp:給Observable發(fā)射的數(shù)據(jù)項(xiàng)附加一個(gè)指定的時(shí)間戳。
  • Using:創(chuàng)建一個(gè)只在Observable生命周期內(nèi)存在的一次性資源。
  • To:將Observable轉(zhuǎn)換為另一個(gè)對象或數(shù)據(jù)結(jié)構(gòu)。

1. Delay

延遲一段指定的時(shí)間再發(fā)射來自O(shè)bservable的發(fā)射物。

img-Delay

Delay 操作符讓原始 Observable 在發(fā)射每項(xiàng)數(shù)據(jù)之前都暫停一段指定的時(shí)間段。效果是Observable發(fā)射的數(shù)據(jù)項(xiàng)在時(shí)間上向前整體平移了一個(gè)增量。

1.1 delay(long delay, TimeUnit unit)

延遲指定時(shí)間段后發(fā)射原始Observable發(fā)射的數(shù)據(jù)序列,如果發(fā)生異常的話,會立即發(fā)射通知給觀察者。

img-delay-time

1.2 delay(Function<T, ObservableSource> itemDelay)

使用一個(gè)函數(shù)針對原始 Observable 的每一項(xiàng)數(shù)據(jù)返回一個(gè) Observable ,它監(jiān)視返回的這個(gè) Observable ,當(dāng)任何那樣的 Observable 終止時(shí),delay 返回的 Observable 就發(fā)射關(guān)聯(lián)的那項(xiàng)數(shù)據(jù)。

img-delay-function

1.3 delay(ObservableSource subscriptionDelay, Function<T, ObservableSource> itemDelay)

延遲直到 subscriptionDelay 發(fā)射第一個(gè)數(shù)據(jù)項(xiàng)后開始訂閱原始 Observable,然后再使用一個(gè)函數(shù)針對原始Observable的每一項(xiàng)數(shù)據(jù)返回一個(gè)Observable,它監(jiān)視返回的這個(gè)Observable,當(dāng)任何那樣的 Observable 終止時(shí),delay 返回的 Observable 就發(fā)射關(guān)聯(lián)的那項(xiàng)數(shù)據(jù)。

img-delay-observable-function

示例代碼:

    // 創(chuàng)建Observable
    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
        //  emitter.onError(new Exception("Test Error!"));
            emitter.onNext(4);
            emitter.onNext(5);
            emitter.onComplete();
        }
    });

    /**
     * 1. delay(long delay, TimeUnit unit,
     *  Scheduler scheduler: 可選參數(shù),指定工作線程
     *  boolean delayError:    可選參數(shù),延遲異常通知到最后
     *  )
     *  延遲指定時(shí)間段后發(fā)射原始Observable發(fā)射的數(shù)據(jù)序列,如果發(fā)生異常的話,會立即發(fā)射通知給觀察者。
     */
    observable.doOnNext(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> doOnNext(1): " + integer);
        }

    }).delay(1, TimeUnit.SECONDS, Schedulers.newThread(), false) // 在子線程中延遲1秒發(fā)射數(shù)據(jù),不延遲異常通知
      .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("--> onSubscribe(1)");
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("--> onNext(1): " + integer);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("--> onError(1): " + e);
            }

            @Override
            public void onComplete() {
                System.out.println("--> onCompleted(1)");
            }
      });

    System.in.read();
    System.out.println("-----------------------------------------------------");
    /**
     *  2. delay(Function<T, ObservableSource<U>> itemDelay)
     *   使用一個(gè)函數(shù)針對原始Observable的每一項(xiàng)數(shù)據(jù)返回一個(gè)Observable,它監(jiān)視返回的這個(gè)Observable,
     *   當(dāng)任何那樣的 Observable 終止時(shí),delay 返回的 Observable 就發(fā)射關(guān)聯(lián)的那項(xiàng)數(shù)據(jù)。
     */
    observable.doOnNext(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> doOnNext(2): " + integer);
        }

    }).delay(new Function<Integer, ObservableSource<Long>>() {
        @Override
        public ObservableSource<Long> apply(Integer integer) throws Exception {
            System.out.println("--> ObservableSource(2): " + integer);
            Observable<Long> timer = Observable.timer(integer, TimeUnit.SECONDS);
            return timer;
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(2)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(2): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(2): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(2)");
        }
    });

    System.in.read();
    System.out.println("-----------------------------------------------------");
    /**
     *  3. delay(ObservableSource subscriptionDelay, Function<T, ObservableSource> itemDelay)
     *  延遲直到subscriptionDelay發(fā)射第一個(gè)數(shù)據(jù)項(xiàng)后開始訂閱原始Observable
     *  然后再使用一個(gè)函數(shù)針對原始Observable的每一項(xiàng)數(shù)據(jù)返回一個(gè)Observable,它監(jiān)視返回的這個(gè)Observable,
     *  當(dāng)任何那樣的 Observable 終止時(shí),delay 返回的 Observable 就發(fā)射關(guān)聯(lián)的那項(xiàng)數(shù)據(jù)。
     */
    observable.doOnNext(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> doOnNext(3): " + integer);
        }
       // 延遲3秒后開始訂閱源Observable,然后對發(fā)射的每項(xiàng)數(shù)據(jù)進(jìn)行function函數(shù)延遲
    }).delay(Observable.timer(3, TimeUnit.SECONDS), new Function<Integer, ObservableSource<Long>>() {
        @Override
        public ObservableSource<Long> apply(Integer integer) throws Exception {
            System.out.println("--> apply(3): " + integer);
            return Observable.timer(integer, TimeUnit.SECONDS);
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(3)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(3): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(3): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(3)");
        }
    });

    System.in.read();

輸出:

--> onSubscribe(1)
--> doOnNext(1): 1
--> doOnNext(1): 2
--> doOnNext(1): 3
--> doOnNext(1): 4
--> doOnNext(1): 5
--> onNext(1): 1
--> onNext(1): 2
--> onNext(1): 3
--> onNext(1): 4
--> onNext(1): 5
--> onCompleted(1)
-----------------------------------------------------
--> onSubscribe(2)
--> doOnNext(2): 1
--> ObservableSource(2): 1
--> doOnNext(2): 2
--> ObservableSource(2): 2
--> doOnNext(2): 3
--> ObservableSource(2): 3
--> doOnNext(2): 4
--> ObservableSource(2): 4
--> doOnNext(2): 5
--> ObservableSource(2): 5
--> onNext(2): 1
--> onNext(2): 2
--> onNext(2): 3
--> onNext(2): 4
--> onNext(2): 5
--> onCompleted(2)
-----------------------------------------------------
--> onSubscribe(3)
--> doOnNext(3): 1
--> apply(3): 1
--> doOnNext(3): 2
--> apply(3): 2
--> doOnNext(3): 3
--> apply(3): 3
--> doOnNext(3): 4
--> apply(3): 4
--> doOnNext(3): 5
--> apply(3): 5
--> onNext(3): 1
--> onNext(3): 2
--> onNext(3): 3
--> onNext(3): 4
--> onNext(3): 5
--> onCompleted(3)

Javadoc: delay(long delay, TimeUnit unit, Scheduler scheduler, boolean delayError)
Javadoc: delay(Function<T, ObservableSource> itemDelay)
Javadoc: delay(ObservableSource subscriptionDelay, Function<T, ObservableSource> itemDelay)

2. Do

注冊一個(gè)動(dòng)作作為原始Observable生命周期事件的監(jiān)聽器。

img-Do

你可以注冊指定的回調(diào),當(dāng)Observable的某個(gè)事件發(fā)生時(shí),Rxjava 會在與 Observable 鏈關(guān)聯(lián)的正常通知集合中調(diào)用它。

在Rxjava中有許多相關(guān)Do的變體,分別進(jìn)行不同場景的事件監(jiān)聽,一般有下面幾種操作方法:

  1. doOnSubscribe(Consumer onSubscribe):一旦有觀察者訂閱了Observable,就會被調(diào)用。
  2. doOnLifecycle(Consumer onSubscribe, Action onDispose): 在觀察者訂閱產(chǎn)生和解除時(shí)被調(diào)用。
  3. doOnNext(Consumer onNext):在 Observable 每次發(fā)射數(shù)據(jù)前被調(diào)用。
  4. doOnEach(Observer observer): 在 Observable 調(diào)用觀察者的所有通知前被調(diào)用。
  5. doAfterNext(Consumer onAfterNext):在 Observable 調(diào)用OnNext通知(數(shù)據(jù)發(fā)射通知)之后被調(diào)用。
  6. doOnError(Consumer onError):注冊一個(gè)動(dòng)作,當(dāng)它的 Observable 由于異常終止調(diào)用 onError 時(shí)會被調(diào)用。
  7. doOnTerminate(Action onTerminate): 當(dāng)Observable終止之前會被調(diào)用,無論是正常還是異常終止。
  8. doAfterTerminate(Action onFinally): 當(dāng)Observable終止之后會被調(diào)用,無論是正常還是異常終止。
  9. doOnComplete(Action onComplete):Observable正常終止調(diào)用 onCompleted 時(shí)會被調(diào)用。
  10. doFinally(Action onFinally):Observable終止之后會被調(diào)用,無論是正常還是異常終止,但是優(yōu)先于doAfterTerminate。
  11. doOnDispose(Action onDispose):在觀察者調(diào)用Disposable的dispose()方法時(shí)被調(diào)用。

示例代碼:

    /**
     *  1. doOnSubscribe(Consumer onSubscribe)
     *  一旦有觀察者訂閱了Observable,就會被調(diào)用
     */
    Observable.just(999).doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe");
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(1)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(1): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(1): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(1)");
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  2. doOnLifecycle(Consumer onSubscribe, Action onDispose)
     *  onSubscribe: 接受觀察者訂閱前的通知,可以在此通知中解除訂閱
     *  onDispose:   接受觀察者調(diào)用解除訂閱通知
     *  在觀察者訂閱產(chǎn)生和解除時(shí)調(diào)用
     */
    Observable.just(999).doOnLifecycle(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnLifecycle onSubscribe(2)");
            // disposable.dispose();  // 可以在觀察者訂閱前直接解除訂閱
        }
    }, new Action() {
        @Override
        public void run() throws Exception {
            System.out.println("----> doOnLifecycle onDispose(2)");
        }
    }).subscribe(new Observer<Integer>() {
        private Disposable disposable;

        @Override
        public void onSubscribe(Disposable d) {
            disposable = d;
            System.out.println("--> onSubscribe(2)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(2): " + integer);
            disposable.dispose(); // 手動(dòng)解除訂閱
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(2): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(2)");
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  3. doOnNext(Consumer onNext)
     *  在Observable每次發(fā)射數(shù)據(jù)前被調(diào)用
     */
    Observable.just(999).doOnNext(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("----> doOnNext(3): " + integer);
        }
    }).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> accept(3): " + integer);
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  4. doOnEach(Observer observer)
     *  在Observable調(diào)用觀察者的所有通知前被調(diào)用
     */
    Observable.just(999).doOnEach(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("----> doOnEach(4) onSubscribe");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("----> doOnEach(4) onNext: " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("----> doOnEach(4) onError: " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("----> doOnEach(4) onComplete");
        }
    }).subscribe(new Observer<Integer>() {

        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(4)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(4): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(4): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(4)");
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  5. doAfterNext(Consumer onAfterNext)
     *  在Observable調(diào)用OnNext通知(數(shù)據(jù)發(fā)射通知)之后被調(diào)用
     */
    Observable.just(999).doAfterNext(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("----> doAfterNext(5): " + integer);
        }
    }).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> onNext(5): " + integer);
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  6. doOnError(Consumer onError)
     *  注冊一個(gè)動(dòng)作,當(dāng)它的Observable由于異常終止調(diào)用 onError 時(shí)會被調(diào)用
     */
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onError(new Exception("Test Error!"));
        }
    }).doOnError(new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception {
            System.out.println("----> doOnError(6): " + throwable);
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(6)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(6): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(6): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onComplete(6)");
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  7.
     *  doOnTerminate(Action onTerminate):  當(dāng)Observable終止之前會被調(diào)用,無論是正常還是異常終止
     *  doAfterTerminate(Action onFinally): 當(dāng)Observable終止之后會被調(diào)用,無論是正常還是異常終止
     */
    Observable.just(999).doOnTerminate(new Action() {
        @Override
        public void run() throws Exception {
            System.out.println("----> doOnTerminate(7)");
        }
    }).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> accept(7): " + integer);
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  8. doOnComplete(Action onComplete)
     *  Observable正常終止調(diào)用 onCompleted 時(shí)會被調(diào)用
     */
    Observable.just(999).doOnComplete(new Action() {
        @Override
        public void run() throws Exception {
            System.out.println("----> doOnComplete(8)");
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(8)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(8): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(8): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onComplete(8)");
        }
    });

    System.out.println("--------------------------------------------");
    /**
     *  9. doFinally(Action onFinally)
     *  Observable終止之后會被調(diào)用,無論是正常還是異常終止,但是優(yōu)先于doAfterTerminate
     */
    Observable.just(999).doFinally(new Action() {
        @Override
        public void run() throws Exception {
            System.out.println("----> doFinally(9)");
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(9)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(9): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(9): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onComplete(9)");
        }
    });
    
    System.out.println("--------------------------------------------");
    /**
     *  10. doOnDispose(Action onDispose)
     *  在觀察者調(diào)用Disposable的dispose()方法時(shí)被調(diào)用
     */
    Observable.just(999).doOnDispose(new Action() {
        @Override
        public void run() throws Exception {
            System.out.println("----> doOnDispose(10)");
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(10)");
            d.dispose();
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(10): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(10): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onComplete(10)");
        }
    });

輸出:

----> doOnSubscribe
--> onSubscribe(1)
--> onNext(1): 999
--> onCompleted(1)
--------------------------------------------
----> doOnLifecycle onSubscribe(2)
--> onSubscribe(2)
--> onNext(2): 999
----> doOnLifecycle onDispose(2)
--------------------------------------------
----> doOnNext(3): 999
--> accept(3): 999
--------------------------------------------
--> onSubscribe(4)
----> doOnEach(4) onNext: 999
--> onNext(4): 999
----> doOnEach(4) onComplete
--> onCompleted(4)
--------------------------------------------
--> onNext(5): 999
----> doAfterNext(5): 999
--------------------------------------------
--> onSubscribe(6)
----> doOnError(6): java.lang.Exception: Test Error!
--> onError(6): java.lang.Exception: Test Error!
--------------------------------------------
--> accept(7): 999
----> doOnTerminate(7)
--------------------------------------------
--> onSubscribe(8)
--> onNext(8): 999
----> doOnComplete(8)
--> onComplete(8)
--------------------------------------------
--> onSubscribe(9)
--> onNext(9): 999
--> onComplete(9)
----> doFinally(9)
--------------------------------------------
--> onSubscribe(10)
----> doOnDispose(10)

Javadoc: doOnSubscribe(Consumer onSubscribe)
Javadoc: doOnLifecycle(Consumer onSubscribe, Action onDispose)
Javadoc: doOnNext(Consumer onNext)
Javadoc: doOnEach(Observer observer)
Javadoc: doAfterNext(Consumer onAfterNext)
Javadoc: doOnError(Consumer onError)
Javadoc: doOnTerminate(Action onTerminate)
Javadoc: doAfterTerminate(Action onFinally)
Javadoc: doOnComplete(Action onComplete)
Javadoc: doFinally(Action onFinally)
Javadoc: doOnDispose(Action onDispose)

3. SubscribeOn

指定Observable自身在哪個(gè)調(diào)度器上執(zhí)行。

img-SubscribeOn

使用調(diào)度器 Scheduler 來管理多線程環(huán)境中Observable的轉(zhuǎn)場。你可以使用 SubscribeOn 操作符指定Observable在一個(gè)特定的調(diào)度器上運(yùn)轉(zhuǎn)。

示例代碼:

    // 查看當(dāng)前線程id
    System.out.println("----> main: threadID = " + Thread.currentThread().getId());

    /**
     *  subscribeOn(Scheduler scheduler)
     *  指定Observable在指定的scheduler上調(diào)度
     */
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            // 查看Observable的工作線程id
            System.out.println("----> SubscribeOn: threadID = " + Thread.currentThread().getId());
            emitter.onNext(999);
            emitter.onComplete();
        }
    }).subscribeOn(Schedulers.newThread())  // 指定Observable的工作線程在子線程
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("--> accept: " + integer);
                }
            });

    System.in.read();

輸出:

----> main: threadID = 1
----> SubscribeOn: threadID = 13
--> accept: 999

Javadoc: subscribeOn(Scheduler scheduler)

4. ObserverOn

指定一個(gè)觀察者在哪個(gè)調(diào)度器上觀察這個(gè)Observable。

img-ObserveOn

使用調(diào)度器 Scheduler 來管理多線程環(huán)境中Observable的轉(zhuǎn)場。你可以使用 ObserveOn 操作符指定Observable在一個(gè)特定的調(diào)度器上發(fā)送通知給觀察者 (調(diào)用觀察者的onNext, onCompleted , onError 方法)。

示例代碼:

    // 查看當(dāng)前線程id
    System.out.println("----> main: threadID = " + Thread.currentThread().getId());

    /**
     *  observeOn(Scheduler scheduler,
     *  boolean delayError,     // 可選參數(shù)是否延遲異常
     *  int bufferSize                    // 指定緩存大小
     *  )
     * 指定觀察者在指定的scheduler線程中調(diào)度
     */
    Observable.just(999).observeOn(Schedulers.newThread(), true, 3)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    // 查看觀察者的線程id
                    System.out.println("--> accept ThreadID: " + Thread.currentThread().getId());
                    System.out.println("--> accept: " + integer);
                }
            });

    System.in.read();

輸出:

----> main: threadID = 1
--> accept ThreadID: 13
--> accept: 999

Javadoc: observeOn(Scheduler scheduler)
Javadoc: observeOn(Scheduler scheduler, boolean delayError)
Javadoc: observeOn(Scheduler scheduler, boolean delayError, int bufferSize)

5. Serialize

強(qiáng)制一個(gè)Observable連續(xù)調(diào)用并保證行為正確,其實(shí)就是同步事件操作。

img-Serialize

一個(gè)Observable可以異步調(diào)用它的觀察者的方法,可能是從不同的線程調(diào)用。這可能會讓Observable行為不正確,它可能會在某一個(gè) onNext 調(diào)用之前嘗試調(diào)用 onCompleted 或 onError 方法,或者從兩個(gè)不同的線程同時(shí)調(diào)用 onNext 方法。使用 Serialize 操作符,你可以糾正這個(gè)Observable的行為,保證它的行為是正確的且是同步的。

示例代碼:

    /**
     *  serialize()
     *  強(qiáng)制一個(gè)Observable連續(xù)調(diào)用(同步)并保證行為正確
     */
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            // 多線程事件調(diào)用
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        emitter.onNext(i + 1);
                    }
                    emitter.onComplete();
                }
            }).start();

            // 多線程事件調(diào)用
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 100; i < 110; i++) {
                        emitter.onNext(i + 1);
                    }
                    emitter.onComplete();
                }
            }).start();
        }
    }).serialize() // 序列化,合法性操作
      .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("--> onSubscribe");
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("--> onNext: " + integer);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("--> onError: " + e);
            }

            @Override
            public void onComplete() {
                System.out.println("--> onComplete");
            }
      });

    System.in.read();

輸出:

---------------------------------------------
下面是沒有使用Serialize()場景,發(fā)現(xiàn)不合法的調(diào)用
--> onSubscribe
--> onNext: 1
--> onNext: 2
--> onNext: 3
--> onNext: 4
--> onNext: 5
--> onNext: 6
--> onNext: 7
--> onNext: 8
--> onNext: 101
--> onNext: 102
--> onNext: 103
--> onNext: 104
--> onNext: 105
--> onNext: 9
--> onNext: 106
--> onNext: 10
--> onNext: 107
--> onComplete
--> onNext: 108     // 不合法的調(diào)用
----------------------------------------------
下面是使用Serialize()場景,合法的事件調(diào)用
--> onSubscribe
--> onNext: 1
--> onNext: 2
--> onNext: 3
--> onNext: 4
--> onNext: 5
--> onNext: 6
--> onNext: 7
--> onNext: 8
--> onNext: 9
--> onNext: 101
--> onNext: 102
--> onNext: 103
--> onNext: 104
--> onNext: 105
--> onNext: 106
--> onNext: 107
--> onNext: 108
--> onNext: 109
--> onNext: 110
--> onComplete

Javadoc: serialize()

6. Materialize

Materialize 將數(shù)據(jù)項(xiàng)和事件通知都當(dāng)做數(shù)據(jù)項(xiàng)發(fā)射。

img-Materialize

一個(gè)合法的有限的Obversable將調(diào)用它的觀察者的 onNext 方法零次或多次,然后調(diào)用觀察者的 onCompleted 或 onError 正好一次。 Materialize 操作符將這一系列調(diào)用,包括原來的 onNext 通知和終止通知onCompleted 或 onError 都轉(zhuǎn)換為一個(gè)Observable發(fā)射的數(shù)據(jù)序列。

解析: 將來自原始Observable的通知轉(zhuǎn)換為 Notification 對象,然后它返回的Observable會發(fā)射這些數(shù)據(jù)。

示例代碼:

    /**
     *  materialize()
     *  將來自原始Observable的通知轉(zhuǎn)換為Notification對象,然后它返回的Observable會發(fā)射這些數(shù)據(jù)。
     */
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onError(new Exception("Test Error!"));
            emitter.onComplete();
        }
    }).materialize()
      .subscribe(new Observer<Notification<Integer>>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("--> onSubscribe");
            }

            @Override
            public void onNext(Notification<Integer> integerNotification) {
                System.out.println("--> onNext: " + integerNotification);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("--> onError: " + e);
            }

            @Override
            public void onComplete() {
                System.out.println("--> onComplete");
            }
      });

輸出:

--> onSubscribe
--> onNext: OnNextNotification[1]
--> onNext: OnNextNotification[2]
--> onNext: OnErrorNotification[java.lang.Exception: Test Error!]
--> onComplete

Javadoc: materialize()

7. Dematerialize

Dematerialize 操作符是 Materialize 的逆向過程,它將 Materialize 轉(zhuǎn)換的結(jié)果還原成它原本的形式。

img-Dematerialize

解析: dematerialize 反轉(zhuǎn)這個(gè)過程,將原始Observable發(fā)射的 Notification 對象還原成Observable的通知。

示例代碼:

    /**
     *  dematerialize()
     *  過時(shí)的方法,在Rxjava:2.2.4中已經(jīng)被dematerialize(Function<T, Notification<R>> selector)替代
     *  將原始Observable發(fā)射的 Notification 對象還原成Observable的通知。
     */
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onError(new Exception("Test Error!"));
            emitter.onComplete();
        }
    }).materialize()
      .dematerialize()  // 將Notification 對象還原成Observable的通知
      .subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("--> onSubscribe(1)");
            }

            @Override
            public void onNext(Object o) {
                System.out.println("--> onNext(1): " + o);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("--> onError(1): " + e);
            }

            @Override
            public void onComplete() {
                System.out.println("--> onComplete(1)");
            }
      });

    System.out.println("------------------------------------------------");
    /**
     *  dematerialize(Function<T, Notification<R>> selector)
     *  將原始Observable發(fā)射的 Notification 對象經(jīng)過一個(gè)selector函數(shù)處理后,發(fā)射一個(gè)新的Notification,
     *  還原成Observable的通知。
     */
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onError(new Exception("Test Error!"));
            emitter.onComplete();
        }
    }).materialize()
      .dematerialize(new Function<Notification<Integer>, Notification<Integer>>() {
                @Override
                public Notification<Integer> apply(Notification<Integer> integerNotification) throws Exception {
                    System.out.println("--> apply(2): " + integerNotification);
                    return integerNotification;
                }
      }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("--> onSubscribe(2)");
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("--> onNext(2): " + integer);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("--> onError(2): " + e);
            }

            @Override
            public void onComplete() {
                System.out.println("--> onComplete(2)");
            }
    });

輸出:

--> onSubscribe(1)
--> onNext(1): 1
--> onNext(1): 2
--> onError(1): java.lang.Exception: Test Error!
------------------------------------------------
--> onSubscribe(2)
--> apply(2): OnNextNotification[1]
--> onNext(2): 1
--> apply(2): OnNextNotification[2]
--> onNext(2): 2
--> apply(2): OnErrorNotification[java.lang.Exception: Test Error!]
--> onError(2): java.lang.Exception: Test Error!

Javadoc: dematerialize()
Javadoc: dematerialize(Function<T,Notification<R>> selector)

接續(xù):

后續(xù)的Observable的輔助操作部分請參考: Rxjava2 Observable的輔助操作詳解及實(shí)例(二)

Rx介紹與講解及完整目錄參考:Rxjava2 介紹與詳解實(shí)例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,084評論 2 375