RxJava2的使用

weixin_34194087發表於2017-08-05

不怕跌倒,所以飛翔

特別感謝:
南塵2251的部落格

Rxjava最近使用的時候有很多不記得的了,所以說一定要寫一篇部落格記錄一下,好了廢話不多說,快上車吧!

關聯類庫,這個是最重要的!

   compile 'io.reactivex.rxjava2:rxjava:2.1.2'
   compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

瞭解操作符:

關於RxJava的操作符,我們還要一個一個的說,哎挺頭疼的...哈哈!

Create操作符

這個操作符其實就是一個建立的操作符,這個也是最基本的一個操作符:最基本的寫法,上面已經寫了很多的註釋,基本上都能看明白的!

        Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("a");
                e.onNext("b");
                e.onNext("c");
                e.onNext("d");
                e.onComplete();/*結束的操作符*/
            }
        });

        observable.subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                /*開始的時候執行*/
                Log.e(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(@NonNull String s) {
                /*onNext呼叫的時候執行*/
                Log.e(TAG, "onNext: " + s);
                mTvContent.setText(s);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                /*錯誤的時候執行*/
                Log.e(TAG, "onError: " + e);
            }

            @Override
            public void onComplete() {
                /*complete的時候執行,也就是最後的時候執行*/
                Log.e(TAG, "onComplete: ");
            }
        });
2546238-7bb7a4705f5cb08f.png
onCreate操作符的列印結果

這裡面有一點要說明的,如果你在b和c中間的時候呼叫e.onComplete();
那麼c和d就不會執行的!這裡記住!!!只要是onComplete()呼叫的話就會終止這次操作!

just操作符

就是傳送一個指定內容的操作符

  Observable.just(1, 2, 3, 4, 5)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-0595e63f1bc07057.png
just操作符的列印結果

Map操作符

這個操作符你可以理解為每傳送一個資料,我攔截一下,做出改變之後再傳送出去。

  Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("1");
                e.onNext("2");
                e.onNext("3");
                e.onNext("4");
                e.onComplete();
            }
        }).map(new Function<String, Integer>() {
            @Override
            public Integer apply(@NonNull String s) throws Exception {
                return Integer.valueOf(s) * 10;
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.e(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(@NonNull Integer integer) {
                Log.e(TAG, "onNext: " + integer);
                mTvContent.setText(String.valueOf(integer));
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError: ");
            }

            @Override
            public void onComplete() {
                Log.e(TAG, "onComplete: ");
            }
        });

這個map的操作符裡面是一個Function這個類,傳入的泛型這裡說明一下,前一個是Observable傳送型別的泛型,後面那個是你想改變之後型別的泛型,之後接收的時候Observer會把型別自動轉換成後面那個泛型的型別!(說的有點白話,但是我覺得這樣比較好理解,嘻嘻)

2546238-18cd157542fd092c.png
Map操作符操作符的

Zip操作符

這個操作符就是和Windows的zip檔案似的,就是把兩個Observable進行合併!打成一個包!(但是這裡有一點要注意,兩個數量不同的Observable合併的時候是以最少的為準,很好理解,就是一個多的一個說的兩兩配對,沒有配對的就捨去了唄!單身狗的悲哀)

        /*傳送字串的Observable*/
        Observable<String> mStringObservable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("1");
                e.onNext("2");
                e.onNext("3");
                e.onNext("4");
                e.onNext("5");
                e.onComplete();
            }
        });

        /*傳送數字的Observable*/
        Observable<Integer> mIntObservable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
                e.onNext(4);
                e.onNext(5);
                e.onNext(6);
                e.onComplete();
            }
        });

        Observable.zip(mStringObservable, mIntObservable, new BiFunction<String, Integer, String>() {
            @Override
            public String apply(@NonNull String s, @NonNull Integer integer) throws Exception {
                return String.valueOf(Integer.valueOf(s) + integer);
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.e(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(@NonNull String s) {
                Log.e(TAG, "onNext: " + s);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError: " + e);
            }

            @Override
            public void onComplete() {
                Log.e(TAG, "onComplete: ");
            }
        });

這裡有幾點說明的,那個BiFunction類中傳入的泛型,第一個和第二個是兩個要合併操作符的兩個泛型,第三個是合併之後的泛型,zip的操作符中間的是合併的規則,最後那個Observer的泛型會和合並之後的泛型相同的!列印結果的話就能看出來是以最少的那個數量為標準!

2546238-930b12df9f1e5b7e.png
Zip操作符的列印結果

Concat操作符

這個操作符是把兩個Observable合成一個Observable的操作符

Observable.concat(Observable.just(1, 2, 3), Observable.just(4, 5, 6))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });

這裡說明下就是要合併的兩個操作符應該屬於同一型別的,並且是按照順序進行排列的。

2546238-af9728479de976b8.png
Concat操作符的列印結果

FlatMap操作符的使用

就是將一個Observable轉換成多個Observable進行傳送,然後把多個Observable裝進一個發射器中進行傳送,FlatMap不能保證順序,這點一定要切記!

Observable.just(1, 2, 3, 4)
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(@NonNull Integer integer) throws Exception {
                        List<Integer> mList = new ArrayList<>();
                        for (int i = 0; i < 5; i++) {
                            mList.add(i);
                        }
                        return Observable.fromIterable(mList);
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: ");
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });

這裡簡單說下邏輯,就是傳送1到4四個資料,之後每一個都轉換成0到4四個資料列印出來。但是這裡注意一點就是使用FlatMap的時候,傳入第二個引數(Observable的時候一定要指定一個泛型,這個泛型一定是之後Observer的時候轉換的泛型,切記切記!!!)

這裡面雖然看不出順序問題,但是你一定要記得這中間有這麼個問題!
2546238-c9e441118d557ba0.png
FlatMap操作符的列印結果

concatMap和FlatMap操作符唯一的區別就是能保證順序,就不再這裡寫出程式碼來了!

distinct操作符

去除重複的操作符

 Observable.just(1, 2, 3, 4, 3, 2, 1)
                .distinct()
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: ");
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });

這個是從前面開始,如果之後有重複的話就不會傳送了!


2546238-d35608929612edf9.png
distinc操作符的列印結果

Filter操作符

過濾操作符,你自己指定一個規定,自己過濾掉不想要的就可以了

  Observable.just(12, 53, 34, 21, 18, 20, 39)
                .filter(new AppendOnlyLinkedArrayList.NonThrowingPredicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) {
                        return integer >30;
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });

這裡面filter過濾的時候會傳入一個物件,這個物件可以是AppendOnlyLinkedArrayList.NonThrowingPredicate或者是Predicate結果都是一樣的,什麼區別我還真的不知道,希望哪位大神幫忙講解下,謝謝!接著說其實這裡面就是返回一個過濾的方法,結果是true和false,從而進行過濾!

2546238-8b2897a2dc7827cd.png
filter操作符的列印結果

buffef操作符

這個操作符是buffef(count,skip)這樣的,作用就是把一個Observable按照你指定的數量count每次Observable從中取出count個元素,每一個Observable是裡面包含count個專案(如果個數夠的話,不夠的話就取剩下的),這裡要說明一下,count是代表每次取出的數量,skip是步長(也就是每次跳過的個數)。

 Observable.just(1, 2, 3, 4, 5, 6)
                .buffer(3, 2)
                .subscribe(new Observer<List<Integer>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull List<Integer> integers) {
                        Log.e(TAG, "onNext: " + integers);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-a4eca39dddd01254.png
buffer的列印結果

說明一下這個列印結果:首先從just中取出3個也就是count個個數,傳送有一個Observable,然後跳過2個也就是skip繼續取count個元素髮送一個Observable,依次取,最後一個由於只有兩個了,所以只取了2個

timer操作符

首先說明一下在2.0當中timer已經變成一個定時任務了,就是傳送一個指定(延遲)時間的請求,而不再是執行間隔邏輯了,間隔邏輯已經被interval取代了,下面會進行講解的!

  Observable.timer(1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())/*發生的執行緒*/
                .observeOn(AndroidSchedulers.mainThread())/*回撥的執行緒*/
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Long aLong) {
                        Log.e(TAG, "onNext: " + String.valueOf(aLong));
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-59f99081bde5ac85.png
timer的列印結果

注意一點問題:就是timer會建立一個新的執行緒去執行!

interval操作符

這個操作符就相當於一個定時的請求了,會一直執行的

  Observable.interval(1, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Long aLong) {
                        Log.e(TAG, "onNext: " + String.valueOf(aLong));
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-5906b6bdc7bb58b7.png
interval操作符的列印結果

如果想要停止的話可以使用Disposable 這個物件的dispose()方法

doOnNext操作符

其實它不算做操作符,只是比較常用
它的作用是讓訂閱者在接收到資料之前乾點有意思的事情。假如我們在獲取到資料之前想先儲存一下它,我們可以這樣實現。

   Observable.just(1, 2, 3, 4, 5)
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e(TAG, "doOnNext: 這裡做一些操作就可以了");
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-a741cc1eb538f71c.png
doOnNext的列印結果

其實就是在每次傳送之前先走doOnNext方法進行一些操作,它會在onNext之前呼叫。

skip操作符

這個操作符其實就是跳過多少個條目之後執行,沒有什麼好說的,看一下列印結果就可以了!

Observable.just(1, 2, 3, 4, 5, 6, 7)
                .skip(3)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-14377427ac8557be.png
skip操作符的列印結果

take操作符

take操作符的作用就是最多能接受多少個引數,這個是從頭開始來的。

 Observable.just(1, 2, 3, 4, 5, 6, 7)
                .take(4)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-9ab4c13fa2422c0d.png
take操作符的列印結果

debounce操作符

這個操作符的作用就是去掉髮送頻率過快的項

 Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {

                e.onNext("1");// skip
                Thread.sleep(400);
                e.onNext("2"); // deliver
                Thread.sleep(505);
                e.onNext("3"); // skip
                Thread.sleep(100);
                e.onNext("4"); // deliver
                Thread.sleep(605);
                e.onNext("5"); // deliver
                Thread.sleep(510);
                e.onComplete();
            }
        })
                .debounce(500, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.e(TAG, "onNext: " + s);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: " + e);
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-3d278c49212863a8.png
debounce操作符的列印結果

這個操作符還是要說一下的!他是去除傳送較為頻繁的項,這裡指定的是500毫秒,所以就把傳送在500毫秒以內的全部清除掉了。

defer操作符

這個操作符的作用就是把之前的Observable轉換成一個新的Observable傳送出來,如果沒有的話他就不傳送了,我是這麼理解的!

 Observable.defer(new Callable<ObservableSource<Integer>>() {
            @Override
            public ObservableSource<Integer> call() throws Exception {
                return Observable.just(1, 2, 3);
            }
        })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: ");
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
2546238-b11c1e7be3229ad7.png
defer操作符的列印結果

last操作符

這個操作符是獲取最後一個傳送項

 Observable.just(1,2,3,4,5)
                .last(1)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e(TAG, "accept: " + integer);
                    }
                });

其實這裡我測試過,這個last後面的引數如論傳入多少獲取的都是最後一項,寫得是預設的條目,這裡我還是不太理解,希望理解的大神說一下!

merge操作符

這個操作符的作用就是合併兩個Observable

  Observable.merge(Observable.just(1, 2, 3), Observable.just(4, 5, 6))
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e(TAG, "accept: " + integer);
                    }
                });
2546238-ddbb406495b9030d.png
Merge操作符的列印結果

reduce操作符

每次用一個方法處理一個值,可以有一個 seed 作為初始值。
其實這個操作符的理解就是用一個方法把兩個物件操作一下,然後合成了一個物件在操作一下,最後返回了一個物件.

 Observable.just(1, 2, 3, 4, 5, 6)
                .reduce(10, new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                        return integer + integer2;
                    }
                })
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e(TAG, "accept: " + integer);
                    }
                });
2546238-f4c9d90348f71a6b.png
reduce操作符的列印結果

這裡還是說明一下,這個呢就是傳送1到6,6個數字,但是中間經過了reduce方法之後,使得這一次的結果和上次的結果進行相加,前面那個10 是一個初始值。

scan操作符

其實這個操作符和上面的reduce操作符類似,但是不同的是他會把每一個步驟都列印出來,而reduce只會列印結果

Observable.just(1, 2, 3, 4, 5, 6)
                .scan(10, new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                        return integer + integer2;
                    }
                })
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e(TAG, "accept: " + integer);
                    }
                });

程式碼都差不多,只是列印結果略有不同


2546238-c794dc3336cbde6d.png
scan操作符的列印結果

基本上的操作符就講到這裡吧!我也是能力有限,寫一半加深一下自己的印象,也希望對其他朋友有幫助!!!
下次就看看實際專案中怎麼用吧!!!
Demo地址

相關文章