1. 程式人生 > >8章 RxJava高階用法(二)

8章 RxJava高階用法(二)

CSDN學院課程地址

8. RxJava高階用法(二)

8.1 Subject的介紹

Subject可以看成是一個橋樑或者代理,在RxJava中同時充當了Observer和Observable的角色,即事件流的傳送方和接收方。因為它是一個Observer,它可以訂閱一個或多個Observable;又因為它是一個Observable,它可以轉發它收到(Observe)的資料,也可以發射新的資料。為了方便演示,在開始講解Subject之前,我們統一創建出SubjectObserver

static class SubjectObserver<T extends String> implements Observer<String> {

    String name;

    public SubjectObserver(String name) {
        this.name = name;
    }

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

    @Override
    public void onComplete() {
        System.out.println(name + " onComplete");
    }

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(java.lang.String s) {
        System.out.println(name + " onNext=" + s);
    }
}

8.2 PublishSubject

PublishSubject不會改變事件的傳送順序。如果在已經發送了一部分事件之後註冊的observer,是不會收到之前傳送的事件

public static void publishSubject() {
    PublishSubject publishSubject = PublishSubject.create();
    publishSubject.subscribe(new SubjectObserver<>("first"));
    publishSubject.onNext("1");
    publishSubject.onNext("2");
    publishSubject.subscribe(new SubjectObserver<>("seconde"));
    publishSubject.onNext("3");
    publishSubject.onComplete();
}

輸出結果

first onNext=1
first onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete

8.3 BehaviorSubject

BehaviorSubject會創建出帶有預設值的事件流。當BehaviorSubject第一次被observer註冊時,如果observable中沒有發射資料項的時候,就會將預設值發給observer;如果observable中有發射過資料項的時候,就會將最近發射的資料項發給observer

public static void behaviorSubject(View view) {
    BehaviorSubject<String> behaviorSubject = BehaviorSubject.createDefault("預設值");
    behaviorSubject.subscribe(new SubjectObserver<String>("first"));
    behaviorSubject.onNext("1");
    behaviorSubject.onNext("2");
    behaviorSubject.subscribe(new SubjectObserver<String>("seconde"));
    behaviorSubject.onNext("3");
    behaviorSubject.onComplete();
}

輸出結果

first onNext=預設值
first onNext=1
first onNext=2
seconde onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete

8.4 ReplaySubject

ReplaySubject無論什麼時候註冊observer,無論何時通過ReplaySubject發射的所有事件,均會發送給新的observer

public static void replaySubject(View view) {
    ReplaySubject<String> replaySubject = ReplaySubject.create();
    replaySubject.subscribe(new SubjectObserver<>("first"));
    replaySubject.onNext("1");
    replaySubject.onNext("2");
    replaySubject.subscribe(new SubjectObserver<>("seconde"));
    replaySubject.onNext("3");
    replaySubject.onComplete();
}

輸出結果

first onNext=1
first onNext=2
seconde onNext=1
seconde onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete

8.5 AsyncSubject

只有當AsyncSubject呼叫onComplete方法時,才會將AsyncSubject中的最後一個事件傳遞給observer。如果不呼叫onComplete方法,則不會給observer傳送任何事件

public static void asyncSubject(View view) {
    AsyncSubject asyncSubject = AsyncSubject.create();
    asyncSubject.subscribe(new SubjectObserver<String>("first"));
    asyncSubject.onNext("1");
    asyncSubject.onNext("2");
    asyncSubject.onNext("3");
    asyncSubject.onComplete();
    asyncSubject.subscribe(new SubjectObserver<String>("seconde"));
    asyncSubject.onComplete();
}

輸出結果

first onNext=3
first onComplete
seconde onNext=3
seconde onComplete

8.6 轉發資料

每種Subject都可以當作是轉發資料的橋樑,在轉發資料的過程中,具體使用哪種應該參考對應的應用場景,通常在元件之間的通訊就需要用到Subject。比如下面這個例子,從元件A中將資訊傳遞給元件B,元件B會收到元件A傳送過來的訊息,如果需要元件B將資訊傳遞給元件B,則需要將程式碼的觀察者角色和被觀察者角色調換過來。通常情況下,元件A和元件B都會同時依附於同一個Activity或Fragment,在Activity或Fragment中應該提供獲取Subject的方法,讓元件雙方可以獲取橋樑,從而互相subscribe,最終形成通訊

public static void transpondData(View view){
    //元件A
    Observable<String> observable = Observable.fromArray("123","456","789");
    ReplaySubject<String> replaySubject = ReplaySubject.create();

    observable.subscribe(replaySubject);
    replaySubject.subscribe(new SubjectObserver<>("B"));//元件B
}

輸出結果

B onNext=123
B onNext=456
B onNext=789
B onComplete

8.7 小結

  1. PublishSubject:從註冊時開始接收新的資料項
  2. BehaviorSubject:從註冊時會收到以前最近的一條資料項,如果沒有則收到預設值
  3. ReplaySubject:無論何時註冊,都會收到以前傳送過的所有資料項到新的observer
  4. AsyncSubject:只有呼叫onComplete時,才會收到最後一個數據項
  5. 轉發資料:A可以轉發給B,B可以轉發給A,主要是看誰subscribe誰