RxJava2.0

參考:
RxJava 只看這一篇文章就夠了 (上)
RxJava 只看這一篇文章就夠了 (中)
RxJava 只看這一篇文章就夠了 (下)

這可能是最好的RxJava 2.x 入門教程(一)


導入

implementation 'io.reactivex.rxjava2:rxjava:2.1.14'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'


要素:

Observable
Observer
subscribe

Disposable subscribe = observable.subscribe(observer);

Observable的構造(靜態方法):

一、構造操作符

create、just、fromArray、fromIterable、fromCallable、fromFuture、defer、timer、range、rangeLong、interval、intervalRange、empty、never、error

1. create

onNext傳遞,onComplete結束傳遞

2. just(object ...) 最多10個

3. fromArray(object...) 無限個對象

for (int i = 10; i < 15; i++) {
    list.add(i);
}
Observable.fromIterable(list)...

5. fromCallable(new Callable<Integer>() {...})

有一個返回值,即不是直接傳入object而已
如:

Observable. fromCallable(new Callable<List<Integer>>() {
    @Override
    public List<Integer> call() throws Exception {
        List<Integer> list = new ArrayList<>();
        for (int i = 10; i < 15; i++) {
            list.add(i);
        }
        return list;
    }
})

如上對比fromIterable,相當於把list的創建過程寫進Callable的call方法中

6. fromFuture(future)

FutureTask future= new FutureTask(...)

增加可操作Callable的cancel等方法,通過get等獲取Callable的返回值

7. defer

直到被觀察者被訂閱後纔會創建被觀察者

8. timer

指定時間後發送一個`0L`

9. range(int start, int count)

從start開始,+1 count次

10. rangeLong

同上  `range(int start, int count)`
從start開始,+1 count次

11. interval

從0開始發送 +1

12. intervalRange

同上 限定了發送的個數

13. empty()

直接發送 onComplete() 事件

14. never()

不發送任何事件

15. error()

發送 onError() 事件

二、轉換操作符

map、flatMap、concatMap、filter、buffer、groupBy、scan、window

1. map

轉換數據類型

2. flatMap

將一個Observable轉換爲另一種Observable
輸出無序(需要在新Observable添加delay才能看出),與concatMap區分

Observable.just(1, 2, 3)
        .flatMap(new Function<Integer, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Integer integer) throws Exception {
                List<String> list = new ArrayList<>();
                list.add("hello" + integer);
                return Observable.fromIterable(list).delay(0, TimeUnit.MILLISECONDS);
            }
        })
        .subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                輸出:hello1
                      hello2
                      hello3
            }
        });

3. concatMap

同上,只是`concatMap`爲有序輸出,`flatMap`無序輸出

4. buffer(count, skip)

按長度分割爲集合

Observable.just(1,2,3,4,5)
        .buffer(3, 2)
        .subscribe(new Consumer<List<Integer>>() {
            @Override
            public void accept(List<Integer> list) throws Exception {
                輸出:[123]
                      [345]
                      [5]
            }
        });

5. groupBy

將發送的數據進行分組,每個分組都會返回一個Observable

Observable.just(1, 2, 3, 4, 5, 6)
       .groupBy(new Function<Integer, Integer>() {
           @Override
           public Integer apply(Integer integer) throws Exception {
               return integer % 3;    //①
           }
       })
       .subscribe(new Consumer<GroupedObservable<Integer, Integer>>() {
           @Override
           public void accept(final GroupedObservable<Integer, Integer> stringIntegerGroupedObservable) throws Exception {
               Lcat.print("----------A---------", stringIntegerGroupedObservable.getKey());
               stringIntegerGroupedObservable.subscribe(new Consumer<Integer>() {
                   @Override
                   public void accept(Integer integer) throws Exception {
                       if (stringIntegerGroupedObservable.getKey() == 2) {  //stringIntegerGroupedObservable.getKey()即可獲取①處的值
                           輸出餘數爲2的值:2
                                            5
                       }
                   }
               });
           }
       });

6. window

按照實際劃分窗口,將數據發送給不同的 Observable

Observable.just(1, 2, 3, 4, 5)
        .window(2)
        .subscribe(new Consumer<Observable<Integer>>() {
            @Override
            public void accept(Observable<Integer> integerObservable) throws Exception {
                Lcat.print("-------------------");
                integerObservable.subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                       輸出:-------------------
                                   1
                                   2
                                 -------------------
                                   3
                                   4
                                 -------------------
                                   5
                    }
                });
            }
        });

三、組合操作符

concat、concatArray、concatArrayDelayError、merge、mergeArray、mergeArrayDelayError、zip、combineLatest、combineLatestDelayError、reduce、collect、startWith、startWithArray、count

1. concat

處理最多4個Observable,前一個結束纔讀下一個,可以應用爲,先讀緩存,再請求網絡; 相當於串聯
調用onNextonComplete標記

Observable.concat(Observable.just(1, 2).delay(1,TimeUnit.SECONDS), Observable.just("a"))
        .subscribe(new Consumer<Serializable>() {
            @Override
            public void accept(Serializable serializable) throws Exception {
             輸出:
                   (1s後)
                     1
                     2
                     a
            }
        });

2. concatArray

同上,可以多於4個Observable

3. merge

同上,不用等到 發射器 A 發送完所有的事件再進行發射器 B 的發送。相當於並聯
如上例,輸出:

    a
  (1s後)
    1
    2   

4. mergeArray

同上

5. concatArrayDelayError

6. mergeArrayDelayError

以上關於concat和merge的方法都是處理多個Observable的,發送onError之後都會終斷繼續發送事件。所以用`concatArrayDelayError`和`mergeArrayDelayError`可以防止,使所有事件發送完成再發送onError事件

7. zip

依次合併幾個事件,一對一,二對二,發送次數爲次數少的個數,多的部分則不處理
Observable.zip(Observable.just(1, 3), Observable.just("a", "b", "c", "d"), new BiFunction<Integer, String, Object>() {
    @Override
    public Object apply(Integer integer, String s) throws Exception {
        return integer + s;
    }
}).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                 輸出:1a
                       3b
            }
        });

8. combineLatest

與zip類似,但是其與時間有關,只會和與其最近發送的事件結合

9. combineLatestDelayError

同上,延遲發送onError事件

10. reduce

每次用一個方法處理一個值,可以有一個 seed 作爲初始值
Observable.just(1, 2, 3, 4)
        .reduce(8, new BiFunction<Integer, Integer, Integer>() {    //初始值爲8,無則爲0
            @Override
            public Integer apply(Integer integer, Integer integer2) throws Exception {
                return integer + integer2;
            }
        })
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                輸出:18
                 (即:8+1=9 9+2=11 11+3=14 14+4=18)
            }
        });

11. scan

同上,區別是會輸出過程
如上例,輸出:
    8
    9
    11
    14
    18

12. collect

將數據收集到數據結構當中,如集合等
Observable.just(1, 2, 10)
        .collect(new Callable<List<Integer>>() {
            @Override
            public List<Integer> call() throws Exception {
                List<Integer> list = new ArrayList<>();
                list.add(333);
                return list;
            }
        }, new BiConsumer<List<Integer>, Integer>() {
            @Override
            public void accept(List<Integer> list, Integer integer) throws Exception {
                list.add(integer);
            }
        }).subscribe(new Consumer<List<Integer>>() {
    @Override
    public void accept(List<Integer> list) throws Exception {
        Lcat.print("list", list);    // [333, 1, 2, 10]
    }
});

13. startWith

14. startWithArray

在發送事件之前追加事件,`startWith()` 追加一個事件,`startWithArray()` 可以追加多個事件

15. count

返回被觀察者發送事件的數量
Observable.just(1, 2, "65")
        .count()
        .subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Lcat.print("事件個數爲:", aLong);    // 事件個數爲:3
            }
        });

四、功能操作符

delay、doOnEach、doOnSubscribe、doOnNext、doAfterNext、doOnComplete、doOnError、doOnDispose、doOnLifecycle、doOnTerminate、doAfterTerminate、doFinally

1. delay (1, TimeUnit.SECOND)

延遲一段時間發送事件

2. doOnEach (Consumer/Observer)

每發送一件個事件之前都會先回調這個方法,即onNextonErroronComplete方法之前都會先走doOnEach方法(onSubscribe之前不會);

3. doOnSubscribe (Consumer)

onSubscribe()之前都會回調該方法;

4. doOnNext (Consumer)

onNext 方法之前都會先走該方法;(接收到數據之前的操作,如保存數據到數據庫等)

5. doAfterNext (Consumer)

onNext方法之後都會先走該方法;

6. doOnComplete (Action)

onComplete()之前都會回調這個方法;

7. doOnError (Consumer)

onError()之前都會回調這個方法;

8. doOnDispose (Action)

調用 Disposable 的 dispose() 之後回調該方法;

9. doOnLifecycle (Customer, Action)

在回調 onSubscribe 之前回調該方法的第一個參數的回調方法,可以使用該回調方法決定是否取消訂閱。第二個參數的回調方法的作用與 doOnDispose() 是一樣的

10. doOnTerminate (Action)

在 onError 或者 onComplete 發送之前回調;

11. doAfterTerminate (Action)

在onError 或者 onComplete 發送之後回調;

12. doFinally (Action)

所有事件發送完畢之後回調該方法。

13. onErrorReturn (Function)

執行完onError方法之後,後續的onNext不會被執行,但是會執行一次onErrorReturn回調的方法,作爲最後一個onNext的值。
Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(1);
        e.onError(new NullPointerException());
        e.onNext(2);
        e.onNext(3);
    }
}).onErrorReturn(new Function<Throwable, Integer>() {
    @Override
    public Integer apply(Throwable throwable) throws Exception {
        Lcat.print("e", throwable);
        return 404;
    }
}).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        Lcat.print("i", integer);   // 輸出: 1,404  不會輸出2和3
    }
});

14. onErrorResumeNext (Function/Observable)

在執行onError之後,可以繼續發送該方法內的事件,new Error()或 new Exception();

15. onExceptionResumeNext (Observable)

同上,但是隻能捕捉Exception,只能是new Exception();

16. retry (/2/Predicate/2,Predicate/BiPredicate)

出現錯誤事件,則會重新發送**所有**事件;

17. retryUntil (BooleanSupplier)

出現錯誤事件之後,可以通過此方法判斷是否繼續發送事件。

18. retryWhen (Function)

如果返回的被觀察者發送 Error 事件則之前的被觀察者不會繼續發送事件,如果發送正常事件則之前的被觀察者會繼續不斷重試發送事件。

19. repeat (/2)

重複發送事件(執行完所有再重複執行)

20. repeatWhen (Function)

返回一個新的被觀察者設定一定邏輯來決定是否重複發送事件;

21. subscribeOn (線程)

指定被觀察者的線程(多次調用此方法,只有第一次有效)

22. observeOn (線程)

指定觀察者的線程(每指定一次就會生效一次)
Schedulers.computation( )   用於使用計算任務,如事件循環和回調處理
Schedulers.immediate( )     當前線程
Schedulers.io( )        用於 IO 密集型任務,如果異步阻塞 IO 操作。
Schedulers.newThread( )     創建一個新的線程
AndroidSchedulers.mainThread()     Android 的 UI 線程,用於操作 UI。

五、過濾操作符

filter、ofType、skip、distinct、distinctUntilChanged、take、debounce、firstElement、lastElement、elementAt、elementAtOrError

1. filter

過濾(實現方法一目瞭然)

2. ofType

.ofType(Integer.class)  //過濾不是int類型的數據`
可以過濾不符合該類型事件

3. distinct

去重 

4. distinctUntilChanged

去除連續重複的事件

5. skip(count)

跳過前count個的輸出

6. take(count)

只取前count個

7. last

取最後一個

8. debounce(timeout, unit)

去除發送頻率過快的項(去除發送頻率在timeout內的項)

9. firstElement

取事件序列的第一個元素

10. lastElement

取事件序列的最後一個元素

11. elementAt

指定取出事件序列中事件(index超出範圍則不輸出)

12. elementAtOrError

同上,超出範圍會報異常崩潰

六、條件操作符

1. all (new Predicate<>{...})

判斷事件序列是否**全部**滿足某個事件

2. takeWhile (new Predicate<>{...})

設置條件,滿足條件時就會發送該數據,反之則不發送

3. skipWhile (new Predicate<>(){...})

設置條件,滿足條件時不發送該數據,反之則發送。(與`takeWhile`相反)

4. takeUntil (new Predicate<>(){...}

滿足條件的下一次事件不會發送,即不滿足條件的數據中,只發送第一條不滿足的數據;

5. skipUntil(Observable)

當 skipUntil() 中的 Observable 發送事件了,原來的 Observable 纔會發送事件給觀察者。(skipUntil() 裏的 Observable 並不會發送事件給觀察者);

6. sequenceEqual (Observable1, Observable2)

判斷兩個observable發送的事件是否完全相同;

7. contains (object)

判斷事件序列中是否含有某個元素;

8. isEmpty ()

判斷事件序列是否爲空;

9. amb (List<Observable>)

只發送最先發送事件的 Observable 中的事件, 其餘Observable的事件被丟棄;

10. defaultIfEmpty (Object)

如果沒emitter.onNext() 就執行了onComplete,則默認發送該Object對象。

注意

  1. 在Activity銷燬的時候,rx的操作不會結束
    所以可能需要在onDestroy中做出判斷:

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

實踐

這可能是最好的RxJava 2.x 入門教程(五)

  1. 通過create創建網絡請求的observable1
  2. 通過create創建緩存讀取的observable2
  3. 通過concat先讀緩存再讀取網絡 Observable.concat(observable1, observable2)
  4. 調用subscribeOn(Schedulers.io())在子線程處理
  5. 調用observeOn(AndroidSchedulers.mainThread())在主線程顯示數據
  6. 調用doOnNext保存數據
  7. 調用map將json轉換爲實體類
  8. 調用subscribe完畢
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章