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