詳解Android RxJava的使用

鋸齒流沙發表於2018-01-01

簡介

什麼是RxJava? GitHub給出的介紹是:RxJava是ReactiveX(Reactive Extensions)的Java VM實現:用於通過使用可觀察序列來編寫非同步和基於事件的程式的庫。

在我的理解中RxJava主要可以實現非同步任務,和事件匯流排的功能,這也是RxJava的厲害之處。

RxJava的GitHub地址:

github.com/ReactiveX/R…

使用

關於RxJava的使用詳解,該篇文章會介紹更加詳細,而且主要偏向於對RxJava的使用。

建立

建立一個觀察者,有兩種方式實現:建立Observer和Subscriber。

Observer:

Observer<String> observer = new Observer<String>() {
            @Override
            public void onError(Throwable e) {
                Log.i("test", "onError");
            }

            @Override
            public void onComplete() {
                Log.i("test", "onComplete");
            }

            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.i("test", "onSubscribe");
            }

            @Override
            public void onNext(String s) {
                Log.i("test", "onNext----->" + s);
            }
        };
複製程式碼

Subscriber:

Subscriber subscriber = new Subscriber() {
            @Override
            public void onSubscribe(Subscription s) {
                Log.i("test", "onSubscribe");
            }

            @Override
            public void onNext(Object o) {
                Log.i("test", "onNext");
            }

            @Override
            public void onError(Throwable t) {
                Log.i("test", "onError");
            }

            @Override
            public void onComplete() {
                Log.i("test", "onComplete");
            }
        }
複製程式碼

建立被觀察者,並且需要和觀察者訂閱起來,在RxJava中的被觀察者是Observable使用subscribe方法訂閱。

建立被觀察者有三種方式可以實現:

1)使用Observable.create建立

        Observable.create(new ObservableOnSubscribe<String>(){

            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("你好");
            }
        }).subscribe(observer);//訂閱
複製程式碼

在建立方式需要在subscribe方法裡,手動呼叫Observer的onNext、onError、onComplete方法,而onSubscribe方法是自動呼叫的。

RxJava

2)Observable.just 可以使用Observable.just方式來建立一個Observable

Observable.just("你好","hello world").subscribe(observer);
複製程式碼

使用Observable.just建立,然後subscribe訂閱,這種方式會自動呼叫onSubscribe、onNext、onError和onComplete方法。

RxJava

3)Observable.fromArray

使用Observable.fromArray來建立一個Observable物件。

String[] quotations = {"熱愛祖國", "熱愛人民"};
Observable.fromArray(quotations).subscribe(observer);
複製程式碼

RxJava

使用Observable.fromArray建立,然後訂閱,和Observable.just一樣,會自動呼叫觀察者的方法。

觀察者的方法

在上面我們已經建立了一個觀察,建立一個觀察者,其中包括四個方法:onError、onComplete、onSubscribe和onNext。

那麼這幾個方法都表示什麼呢?

onSubscribe:被觀察者訂閱觀察者的時候,就會觸發該方法。

onCompleted:事件佇列完結。RxJava 不僅把每個事件單獨處理,還會把它們看做一個佇列。RxJava 規定,當不會再有新的 onNext 發出時,需要觸發 onCompleted方法作為標誌。

onError: 事件佇列異常。在事件處理過程中出異常時,onError方法會被觸發,同時佇列自動終止,不允許再有事件發出。

onNext:表示普通事件,可以在該方法做一些業務邏輯處理。

操作符

操作符包括普通的操作符、變換操作符、過濾操作符、組合操作符、輔助操作符、錯誤處理操作符、條件操作符、布林操作符和轉換操作符。

普通操作符包括:interval、repeat和intervalRange等等。

使用,如:

        Observable.intervalRange(0,6,0,3,TimeUnit.SECONDS).create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("666");
            }
        }).subscribe(observer);
複製程式碼

intervalRange該操作符是用於延遲執行、並且定期執行。

變換操作符包括:map、flatMap、cast和concatMap等等。

map:指定一個Function物件,將Observable轉換為一個新的Observable併發射。

        Observable.just("你好","hello world").map(new Function<String, String>() {
            @Override
            public String apply(@NonNull String s) throws Exception {
                return s;
            }
        }).subscribe(observer);
複製程式碼

RxJava

flatMap、cast:

        Observable.just("你好","hello world").flatMap(new Function<String, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(@NonNull String s) throws Exception {
                return Observable.just(s);
            }
        }).cast(String.class).subscribe(observer);
複製程式碼

flatMap將Observable發射的資料集合變換為Observable集合,然後將這些Observable發射的資料平坦地放進一個單獨的Observable,而cast則強制將Observable發射的所有資料轉換為指定型別。

RxJava

buffer操作符功能:

1、能一次性集齊多個結果到列表中,訂閱後自動清空相應結果,直到完全清除

2、 也可以週期性的集齊多個結果到列表中,訂閱後自動清空相應結果,直到完全清除

        Observable
                .range(0,5)
                .buffer(2)
                .subscribe(new Observer<List<Integer>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

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

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
複製程式碼

RxJava

Observable
                .just("你好","hello world","我愛我家")
                .buffer(3)
                .subscribe(new Observer<List<String>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull List<String> strings) {
                        Log.i("test",""+strings);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
複製程式碼

RxJava

除了以上的變換操作符,還有groupBy操作符,進行分組操作。

過濾操作符

過濾操作符包括filter、skip、take、element等等。

filter:對Observable產生的結果自定義規則進行過濾,只有滿足條件的結果才提交給訂閱者。

Observable
                .just("你好","hello world","我愛我家")
                .filter(new Predicate<String>() {
                    @Override
                    public boolean test(@NonNull String s) throws Exception {
                        Log.i("test",""+s);
                        return s.equals("你好");
                    }
                }).subscribe(observer);
複製程式碼

RxJava

distinct:去重

        Observable
                .just("你好","hello world","我愛我家","我愛我家")
                .distinct()
                .subscribe(observer);
複製程式碼

RxJava

skip:過濾掉前n項

        Observable
                .just("你好","hello world","我愛我家","我愛我家")
                .skip(2)
                .subscribe(observer);
複製程式碼

RxJava

take:取前n項

        Observable
                .just("你好","hello world","我愛我家","我愛我家")
                .take(2)
                .subscribe(observer);
複製程式碼

RxJava

throttleWithTimeout:如果在限定的時間內,源Observable有新的資料發射出來,該資料就會被丟棄,同時throttleWithTimeout重新開始計時,如果每次都是在計時結束前發射資料,那麼這個限流就會走向極端(只會發射最後一個資料)

Observable
                .just("你好","hello world","我愛我家","我愛我家")
                .throttleWithTimeout(200, TimeUnit.MILLISECONDS)
                .subscribe(observer);
複製程式碼

RxJava

組合操作符

組合操作符包括:merge、startWidth、concat、jion、switch和zip等等。

merge:將多個Observable合併到一個Observable中進行發射。

Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.i("test", "onSubscribe");
            }

            @Override
            public void onNext(@NonNull String s) {
                Log.i("test", "onNext--->" + s);
            }

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

            @Override
            public void onComplete() {
                Log.i("test", "onComplete");
            }
        };

        Observable<String> observable1 = Observable.just("你好", "hello World");
        Observable<String> observable2 = Observable.just("new obj", "mergeobj");
        Observable.merge(observable1, observable2).subscribe(observer);
複製程式碼

rejava

concat:將多個Observable發射的資料合併發射,其具有嚴格的順序,發射順序具有佇列的特點。前一個資料沒有發射完成不會發射後一個資料。

Observable<String> observable1 = Observable.just("你好", "hello World");
Observable<String> observable2 = Observable.just("new obj", "mergeobj");
Observable.concat(observable1, observable2).subscribe(observer);
複製程式碼

rxjava

除了以上的組合操作符,還有zip、combineLastest等。

zip:合併兩個或者多個Obserable發射出的資料項,根據指定的函式變換它們,併發射一個新值。

輔助操作符

輔助操作符包括DO、delay、observeOn、timeout、timeInterval、timestamp、subscribeOn、meterialize和to等。

delay:延遲執行發射資料

Observable<String> observable1 = Observable.just("你好", "hello World");
Observable<String> observable2 = Observable.just("new obj", "mergeobj");
Observable.concat(observable1, observable2).delay(5, TimeUnit.SECONDS).subscribe(observer);
複製程式碼

subscribeOn:指定Obserable自身在那個執行緒上執行。

observeOn:指定Obserable發射出的資料在那個執行緒執行。

其他的操作符讀者可以自行實踐。

錯誤操作符

在rxjava中,錯誤操作符包括catch和retry。

catch能夠攔截原始Observable的onError通知,將它替換為其他資料項或者資料序列,讓產生的Observable能夠正常終止或者根本不終止。 catch實現分為三個不同的操作符:

1、onErrorReturn:返回原有Observable行為的備用Observable, 備用的Observable忽略原有的Observable的onError呼叫,即不會將錯誤傳遞給觀察者,而是發射一個特殊的項,以及呼叫觀察者的onCompleted。

2、onErrorResumeNext:跟onErrorReturn一樣返回備用的Observable,不會呼叫原有的Observable的onError,它會發射備用的Observable資料。

3、onExceptionResumeNext:如果onError收到的Throwable不是一個Exception,它會將錯誤傳遞給觀察者的onError方法,不會使用備用的Observable。

retry:不會將原有的Observable的onError通知傳遞給觀察者,這會訂閱這個Observable,再給它一次機會無錯誤地完成其資料序列,而它總會傳遞onNext通知給觀察者。該操作符有可能造成資料重複,因為重新訂閱。如果超過了重新訂閱的次數,就不會再次訂閱了,而是把最新的一個onError通知傳遞給觀察者。

條件操作符

條件操作符包括:defaultEmpty、skipUntil、amb、skipWhile、takeUtil、takeWhile

defaultEmpty:如果原有的Observable沒有發射資料,就發射一個預設的資料。

skipUntil:訂閱原始的Observable,但是忽略它的發射物,直到第二個Observable發射了一項資料那一刻,它開始發射原始Observable。

布林操作符

布林操作符包括:all、isEmpty、contains、exists和sequenceEqual。

關於條件操作符和布林操作符,讀者可以關注《RxJava操作符(08-條件和布林操作) 》這篇文章,文章地址:

blog.csdn.net/xmxkf/artic…

轉換操作符

轉換操作符能夠將Observable轉換為另一個物件或者資料結構,其中轉換操作符包括:toMap、toMultiMap、toList、toSortedList、nest和getIterator等。

toMap:將原始的Observable發射的所有資料項集合到一個Map中,然後發射該Map。

String s1 = "你好";
        String s2 = "hello world";
        String s3 = "lalala";

        Observable.just(s1,s2,s3).toMap(new Function<String, String>() {
            @Override
            public String apply(@NonNull String s) throws Exception {
                return s;
            }
        }).subscribe(new SingleObserver<Map<String, String>>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onSuccess(@NonNull Map<String, String> stringStringMap) {
                Log.i("test",""+stringStringMap);
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }
        });
複製程式碼

RxJava

toMultiMap:類似於toMap,不同的地方在於map的value是一個集合。

toList:將發射的資料組成一個List。

String s1 = "你好";
        String s2 = "hello world";
        String s3 = "lalala";

        Observable.just(s1,s2,s3).toList().subscribe(new SingleObserver<List<String>>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onSuccess(@NonNull List<String> strings) {
                Log.i("test",""+strings);
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }
        });
複製程式碼

rxjava

關於其他操作符,讀者可以參考《RxJava操作符大全》這篇文章。

RxJava的執行緒控制

前面講解輔助操作符的時候,我們知道使用subscribeOn可以指定Obserable自身在那個執行緒上執行。使用observeOn可以指定Obserable發射出的資料在那個執行緒執行。RxJava預設執行緒是在呼叫subcribe方法的執行緒上進行回撥,但是如果想切換執行緒,就需要使用Scheduler。

在RxJava中內建了以下幾個Scheduler:

1、Scheduler.immediate():執行在當前執行緒,是timeout、timestamp和timeInterval操作符的預設排程器。

2、Scheduler.io():I/O操作使用的Scheduler。

3、Scheduler.newThread():開啟一個新的執行緒執行操作。

2和3的區別就是:2的內部實現了一個無數量上限的執行緒池,重用空閒的執行緒,因此2具有更高的效率。

4、Scheduler.trampoline():可以將任務通過trampoline方法加入佇列,該排程器會按順序處理佇列的任務,是repeat和retry操作符的預設排程器。

5、Scheduler.computation():計算所使用的排程器,它具有固定的執行緒池,大小為cpu核數,注意不要將io操作放到computation中,否則io操作的等待時間會浪費cpu。該排程器是buffer、delay、sample、debounce、interval和skip的預設排程器。

6、AndroidSchedulers.mainThread():表示在主執行緒中執行,該排程器是RxAndroid提供的。

Observable.just("你好","hello world")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
複製程式碼

rxjava

寫到這裡,關於RxJava的知識基本講解完了,相信讀者讀完該文,也懂得使用RxJava了,接下來我更新RxJava結合Retrofix和OkHttp的使用,敬請關注,謝謝!

相關文章