寫在前面的話:RxJava的強大之處不僅在於它的設計思想,更是因為有著各種強大的操作符,操作符讓你可以靈活的處理變換、組合、操縱和處理Observable發射的資料,接下來的幾篇文章會按照操作符的分類逐步講解各個操作符的作用,合理使用這些操作符也許你會達到事半功倍的效果。
本文適用於那些RxJava的初學者進階使用,但是如果你還不知道什麼是RxJava,那麼我只能說
這篇的主題是建立型操作符,也就是建立Observable的操作符,先來看看都有那些操作符吧:
- create()
- from()
- just()
- interval()
- timer()
- empty()
- error()
- range()
- repeat()
- defer()
- never()
1.Create
這個就沒什麼好說的了吧?大多數時候我們都是用這個函式來建立Observable的,
經典的流試呼叫
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
if (!e.isDisposed()) {
e.onNext(1);
}
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
}
});複製程式碼
2.from
from的作用是將一個Iterable, 一個Future, 或者一個陣列轉換成一個Observable,from方法具體有一下幾種:
常用的有frmoArray和fromIterable這兩個,來看個具體例子吧
集合遍歷
List<Integer> ls = new ArrayList<>();
ls.add(1);
ls.add(2);
ls.add(3);
Observable.fromIterable(ls).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});複製程式碼
其他的方法大家自行體會吧
3.just
just是將一個或多個物件轉換成發射這個或這些物件的一個Observable,在某些情況下它其實和from的作用有些類似,或者你也可以理解為這是一個簡版的create方法。來看具體例子:
Observable.just(1).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});複製程式碼
just可以傳入一個或多個物件,然後一次發射出來,對於資料量較小時可以使用這個方法。
4.interval
interval可以建立一個按照給定的時間間隔發射整數序列的Observable,通常我們可以用它來來完成一些週期行的操作,比如心跳,Handler最好的替代品了,來看具體例子:
Observable.interval(2, TimeUnit.SECONDS).subscribe(new Consumer<Long>() {
@Override
public void accept(@NonNull Long aLong) throws Exception {
Log.i(TAG, "accept: "+aLong);
}
});複製程式碼
第一個引數為時間間隔,第二個為時間單位,上述accept()會2S執行一次,在這裡你就可以完成一些週期性任務了。
5.timer
timer可以建立一個在給定的延時之後發射單個資料的Observable,通常可以用它完成一些定時任務,注意它和interval的區別,interval是週期性的(多次),timer是定時的(一次),具體例子:
Observable.timer(5, TimeUnit.SECONDS).subscribe(new Consumer<Long>() {
@Override
public void accept(@NonNull Long aLong) throws Exception {
Log.i(TAG, "accept: "+aLong);
}
});複製程式碼
引數和interval一樣,5s之後執行accept方法
6.empty
empty可以建立一個什麼都不做直接通知完成的Observable。這個操作符的使用範圍就比較窄了,舉一個應用場景,我們做資料快取時通常的實現邏輯是先載入本地快取,如果本地沒有或者已經過期那麼才請求網路,這裡就可以使用empty,假設背地快取不存在,那麼是丟擲異常還是返回null呢?顯然這兩種都不合理,因為如果本地不存在我們需要直接請求網路,一種解決辦法就是當為空的時候直接返回Observable.empty(),同時藉助switchIfEmpty(observable1,observable2)方法完成後續的網路請求。當然你也可以通過concat和first來完成資料的獲取,這是我們後續的文章要說的了。場景說忘了,那到底是不是直接通知完成呢?測試一下就知道了
Observable<Integer> o1 = Observable.empty();
o1.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.i(TAG, "onNext: ");
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});複製程式碼
果然是隻有onComplete執行了。
7.error
error可以建立一個不發射資料以一個錯誤終止的Observable,需要一個Throwable引數,使用場景還是拿快取舉例,比如記憶體快取不存在,網路資料也請求失敗了,那麼我們就可以呼叫這個操作符丟擲一個Throwable。那麼就直接執行到了Observer的onError方法裡裡。測試一下,上面的例子不變,我們把empty換成error,並隨便傳入一個Throwable:
Observable<Integer> o1 = Observable.error(new IOException());
o1.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.i(TAG, "onNext: ");
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});複製程式碼
直接執行了onError方法。
8.range
range可以建立一個發射指定範圍的整數序列的Observable。直接上例子:
Observable.range(0,5).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});複製程式碼
第一個引數為數列的起始元素,第二個為長度,列印結果為:
需要注意的是如果你將第二個引數設為0,將導致Observable不發射任何資料(如果設定為負數,會拋異常)
9. repeat
repeat可以建立一個重複發射指定資料的Observable,你也可以通過repeat(n)指定重複次數。更多時候我們會使用repeat(n)這個方法,具體例子:
Observable.just(1).repeat(5).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});複製程式碼
結果為:
10.defer
defer的作用是隻有當Observer訂閱才建立Observable並且是為每個Observer建立一個新的Observable。
正常情況下:
int a = 10;
Observable<Integer> o2 = Observable.just(a);
a = 20;
o2.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.i(TAG, "accept= " + integer);
}
});複製程式碼
輸出為accept=10,但是如果用defer
Observable<Integer> o1 = Observable.defer(new Callable<ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> call() throws Exception {
return Observable.just(a);
}
});
a = 20;
o1.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.i(TAG, "accept:= " + integer);
}
});複製程式碼
輸出為accept=20,大家仔細看一下上邊兩個例子就理解defer了。
11. never
never可以建立一個不發射資料也不終止的Observable,具體還沒有使用過,也沒想到應用場景大家知道有這麼一個操作符就可以了。
以上就是Observable的常見的建立操作符了,有遺漏的歡迎大家補充,下一篇會介紹常見的變換操作符,敬請期待。