Android從零開始學習Rxjava2(二)—— 創建運算符

rxjava2創建運算符

rxjava2支持鏈式編程,大多數運算符都在Observable上運行並返回一個Observable。 這允許我們在鏈中一個接一個地應用這些運算符。 鏈中的每個運算符都會修改由前一個運算符的運算產生的Observable。

rxjava提供了大量不同種類的運算操作符,根據其分類來劃分,大致可以分爲以下列表

分類 舉例 說明
Creating Observables Create、Defer 、Empty/Never/Throw、From 、Interval 、Just 、Range 、Repeat 、Start 、Timer 創建運算符,用於創建Observable
Transforming Observables Buffer 、FlatMap、GroupBy、Map、Scan、Window 變換運算符,用於將Observable發出的項進行轉換
Filtering Observables Debounce、Distinct、ElementAt、Filter 、First 、IgnoreElements 、Last 、Sample、Skip 、SkipLast 、Take 、TakeLast 過濾運算符,將源Observable發出的項有選擇的過濾
Combining Observables And/Then/When 、CombineLatest、Join 、Merge 、StartWith 、Switch 、Zip 組合運算符,使用多個源Observable創建單個Observable
Error Handling Operators Catch、Retry 錯誤處理運算符,有助於從Observable中恢復錯誤通知
Observable Utility Operators Delay、Do、Materialize/Dematerialize 、ObserveOn、Serialize 、Subscribe 、SubscribeOn、TimeInterval 、Timeout、Timestamp、Using 工具運算符,用於處理常見場景Observable的輔助工具
Conditional and Boolean Operators All 、Amb 、Contains 、DefaultIfEmpty 、SequenceEqual 、SkipUntil、SkipWhile 、TakeUntil、TakeWhile 條件和布爾運算符
Mathematical and Aggregate Operators Average 、Concat、Count 、Max、Min 、Reduce、Sum 運算和聚合運算符
Backpressure Operators backpressure operators 被壓策略運算
Connectable Observable Operators Connect、Publish 、RefCount 、Replay 可連接的可觀察操作符,具有更精確控制的訂閱動態的專業觀察者
Operators to Convert Observables To 轉換Observables的運算符,將Observable轉換爲另一個對象或數據結構

這麼一看感覺東西不少,但其實rxjava2中已經去掉、替換了許多常用的運算符和場景的實現方法,我們先一步一步來,選取其中簡單高頻的運算操作符,從易到難慢慢了解下,這一章就先看下常見創建Observable的方法。


Create

使用Create運算符從頭開始創建Observable。適當地調用觀察者的onNext,onError和onCompleted方法。一個格式良好的Observable必須嘗試只調用一次觀察者的onCompleted方法或者只調用一次onError方法,並且此後不得嘗試調用任何觀察者的其他方法。
在這裏插入圖片描述

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                for (int i = 1; i < 3; i++) {
                    emitter.onNext("emitter "+i);
                }
                emitter.onComplete();
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            public void onNext(String s) {
                Log.d(TAG, " onNext : s : " + s);
            }
            @Override
            public void onError(Throwable e) {
            }
            @Override
            public void onComplete() {
                Log.d(TAG, " onComplete");
            }
        });

打印結果

onNext : s : emitter 1
onNext : s : emitter 2
onComplete

Just

創建一個發出特定項目的Observable。Just只是簡單地發出數組或者你有什麼,不變 ,作爲單個項目發出。當just後傳入item是String時,發射出來的爲onNext(String s);當just後傳入的item是string[]時,發射出來的爲onNext(String[] strings)。
在這裏插入圖片描述
下面我舉下例子,說明下:

當just後傳入item是String時

Observable.just("0","1","2","3","4","5","6","7","8","9")
          .subscribe(new Consumer<String>() {
              @Override
              public void accept(String s) throws Exception {
                  Log.d(TAG, " accept : value : " + s);
              }
          });

打印結果爲

onNext : accept : 0
onNext : accept : 1
onNext : accept : 2
onNext : accept : 3
onNext : accept : 4
onNext : accept : 5
onNext : accept : 6
onNext : accept : 7
onNext : accept : 8
onNext : accept : 9

當just後傳入item是string[]時

String str[] = {"0","1","2","3","4","5","6","7","8","9"};
Observable.just(str)
        .subscribe(new Consumer<String[]>() {
            @Override
            public void accept(String[] strings) throws Exception {
                Log.d(TAG, " accept : value String[] length: " + strings.length);
            }
        });

打印結果

accept : value String[] length: 10

與rxjava1.0不同的是,rxjava2不在允許傳遞null,rxjava2 just中直接傳遞null會拋出異常,而且just可傳遞的item個數最多隻能是10個。

Observable.just(null);//會造成異常

查看just源碼可以看見以下代碼

public static <T> Observable<T> just(T item) {
        ObjectHelper.requireNonNull(item, "The item is null");
        return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}
    
public static <T> T requireNonNull(T object, String message) {
        if (object == null) {
        	//拋出異常
            throw new NullPointerException(message);
        }
        return object;
}

fromArray

將各種其他對象和數據類型轉換爲Observable。與just相同的是,rxjava2 fromArray中直接傳遞null會拋出異常。但與just不同的是fromArray發射數組時,它是逐個發射數組的元素。而just發射數組時,會把它當成一個整體,直接發射出去。
在這裏插入圖片描述

String str[] = {"0","1","2","3","4","5","6","7","8","9"};
Observable.fromArray(str)
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, " accept : value : " + s);
            }
        });
accept : value : 0
accept : value : 1
accept : value : 2
accept : value : 3
accept : value : 4
accept : value : 5
accept : value : 6
accept : value : 7
accept : value : 8
accept : value : 9

Range

創建一個發出特定範圍的連續整數的Observable。Range運算符按順序發出一系列連續的整數,我們可以在其中選擇範圍的起點及其長度。
在這裏插入圖片描述
舉個例子,從5開始輸出10個連續的數

Observable.range(5,10)
          .subscribe(new Consumer<Integer>() {
              @Override
              public void accept(Integer integer) throws Exception {
                  Log.d(TAG, " accept : value : " + integer);
              }
          });

打印結果

accept : value : 5
accept : value : 6
accept : value : 7
accept : value : 8
accept : value : 9
accept : value : 10
accept : value : 11
accept : value : 12
accept : value : 13
accept : value : 14

Interval

Interval運算符返回一個Observable,它發出無限的升序整數序列,並在排放之間選擇一個恆定的時間間隔。

在這裏插入圖片描述

舉個例子,一秒之後開始發送,每次發送間隔兩秒

private final CompositeDisposable disposables = new CompositeDisposable();
private void doSomeWork() {
    Log.d(TAG, " doSomeWork time : "+System.currentTimeMillis());
    disposables.add(Observable.interval(1, 2, TimeUnit.SECONDS)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    Log.d(TAG, " accept : value : " + aLong +", time : "+System.currentTimeMillis());
                }
            }));
}
@Override
protected void onDestroy() {
    super.onDestroy();
    disposables.clear(); // clearing it : do not emit after destroy
}

打印結果

doSomeWork time : 1539339380740
accept : value : 0, time : 1539339381744
accept : value : 1, time : 1539339383743
accept : value : 2, time : 1539339385748
accept : value : 3, time : 1539339387749
accept : value : 4, time : 1539339389748
accept : value : 5, time : 1539339391749

Timer

Timer運算符創建一個Observable,在指定的一段時間後發出一個特定項。
在這裏插入圖片描述

Log.d(TAG, " doSomeWork time : " + System.currentTimeMillis());
Observable.timer(2, TimeUnit.SECONDS)
        .subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Log.d(TAG, " accept : value : " + aLong + ", time : " + System.currentTimeMillis());
            }
        });

打印結果

doSomeWork time : 1539339766572
accept : value : 0, time : 1539339768582

Defer

在觀察者訂閱之前不要創建Observable,併爲每個觀察者創建一個新的Observable。Defer運算符等待觀察者訂閱它,然後它生成一個Observable,通常帶有Observable工廠函數。 它爲每個用戶重新執行此操作,因此儘管每個用戶可能認爲它訂閱了相同的Observable,但實際上每個用戶都有自己的單獨序列。

在這裏插入圖片描述
照樣舉個例子

public class Car {
    private String brand = "QQ";
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public Observable<String> brandDeferObservable() {
        return Observable.defer(new Callable<ObservableSource<? extends String>>() {
            @Override
            public ObservableSource<? extends String> call() {
                return Observable.just(brand);
            }
        });
    }
}
private void doSomeWork() {
    Car car = new Car();
    Observable<String> brandDeferObservable = car.brandDeferObservable();
    car.setBrand("BMW");
    // Even if we are setting the brand after creating Observable
    // we will get the brand as BMW.
    // If we had not used defer, we would have got QQ as the brand.
    brandDeferObservable
            .subscribe(new Consumer<String>() {
                @Override
                public void accept(String s) throws Exception {
                    Log.d(TAG, " accept : value : " + s);
                }
            });
}

由於Defer是在觀察者訂閱它之後生成一個Observable,所以我們打印結果

accept : value : BMW

那如果用just來創建Observable我們看看他們打印結果的區別

public class Car {
    private String brand = "QQ";
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public Observable<String> brandDeferObservable() {
        return Observable.just(brand);
    }
}
private void doSomeWork() {
    Car car = new Car();
    Observable<String> brandDeferObservable = car.brandDeferObservable();
    car.setBrand("BMW");
    brandDeferObservable
            .subscribe(new Consumer<String>() {
                @Override
                public void accept(String s) throws Exception {
                    Log.d(TAG, " accept : value : " + s);
                }
            });
}

打印結果

accept : value : QQ

參考資料,參考但不侷限以下鏈接
http://reactivex.io/documentation/operators.html#transforming

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章