RxJava入門實踐④
最近大家都在學習RXJAVA,作為有理想(mei shi gan)的程序員,RxJava還是很有必要學習下的。
RXJAVA地址: https://github.com/ReactiveX/RxJava
在Rxjava當中最重要的就是操作符,RxJava當中有著龐大的操作符
創建操作符:負責創建Observable對象
- just(?) — 將一個或多個對象轉換成發射這個或這些對象的一個Observable
- from(?) — 將一個Iterable, 一個Future, 或者一個數組轉換成一個Observable
- repeat(?) — 創建一個重復發射指定數據或數據序列的Observable
- repeatWhen(?) — 創建一個重復發射指定數據或數據序列的Observable,它依賴于另一個Observable發射的數據
- create(?) — 使用一個函數從頭創建一個Observable
- defer(?) — 只有當訂閱者訂閱才創建Observable;為每個訂閱創建一個新的Observable
- range(?) — 創建一個發射指定范圍的整數序列的Observable
- interval(?) — 創建一個按照給定的時間間隔發射整數序列的Observable
- timer(?) — 創建一個在給定的延時之后發射單個數據的Observable
- empty(?) — 創建一個什么都不做直接通知完成的Observable
- error(?) — 創建一個什么都不做直接通知錯誤的Observable
- never(?) — 創建一個不發射任何數據的Observable
變換操作符:對Observable發射的數據執行變換操作的各種操作符
- map( ) — 對序列的每一項都應用一個函數來變換Observable發射的數據序列
- flatMap( ), concatMap( ), and flatMapIterable( ) — 將Observable發射的數據集合變換為Observables集合,然后將這些Observable發射的數據平坦化的放進一個單獨的Observable
- switchMap( ) — 將Observable發射的數據集合變換為Observables集合,然后只發射這些Observables最近發射的數據
- scan( ) — 對Observable發射的每一項數據應用一個函數,然后按順序依次發射每一個值
- groupBy( ) — 將Observable分拆為Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據
- buffer( ) — 它定期從Observable收集數據到一個集合,然后把這些數據集合打包發射,而不是一次發射一個
- window( ) — 定期將來自Observable的數據分拆成一些Observable窗口,然后發射這些窗口,而不是每次發射一項
- cast( ) — 在發射之前強制將Observable發射的所有數據轉換為指定類型
過濾操作符:用于過濾和選擇Observable發射的數據序列
- filter( ) — 過濾數據
- takeLast( ) — 只發射最后的N項數據
- last( ) — 只發射最后的一項數據
- lastOrDefault( ) — 只發射最后的一項數據,如果Observable為空就發射默認值
- takeLastBuffer( ) — 將最后的N項數據當做單個數據發射
- skip( ) — 跳過開始的N項數據
- skipLast( ) — 跳過最后的N項數據
- take( ) — 只發射開始的N項數據
- first( ) and takeFirst( ) — 只發射第一項數據,或者滿足某種條件的第一項數據
- firstOrDefault( ) — 只發射第一項數據,如果Observable為空就發射默認值
- elementAt( ) — 發射第N項數據
- elementAtOrDefault( ) — 發射第N項數據,如果Observable數據少于N項就發射默認值
- sample( ) or throttleLast( ) — 定期發射Observable最近的數據
- throttleFirst( ) — 定期發射Observable發射的第一項數據
- throttleWithTimeout( ) or debounce( ) — 只有當Observable在指定的時間后還沒有發射數據時,才發射一個數據
- timeout( ) — 如果在一個指定的時間段后還沒發射數據,就發射一個異常
- distinct( ) — 過濾掉重復數據
- distinctUntilChanged( ) — 過濾掉連續重復的數據
- ofType( ) — 只發射指定類型的數據
- ignoreElements( ) — 丟棄所有的正常數據,只發射錯誤或完成通知
結合操作符:用于組合多個Observables的組合使用
- startWith( ) — 在數據序列的開頭增加一項數據
- merge( ) — 將多個Observable合并為一個
- mergeDelayError( ) — 合并多個Observables,讓沒有錯誤的Observable都完成后再發射錯誤通知
- zip( ) — 使用一個函數組合多個Observable發射的數據集合,然后再發射這個結果
- and( ), then( ), and when( ) — (rxjava-joins) 通過模式和計劃組合多個Observables發射的數據集合
- combineLatest( ) — 當兩個Observables中的任何一個發射了一個數據時,通過一個指定的函數組合每個Observable發射的最新數據(一共兩個數據),然后發射這個函數的結果
- join( ) and groupJoin( ) — 無論何時,如果一個Observable發射了一個數據項,只要在另一個Observable發射的數據項定義的時間窗口內,就將兩個Observable發射的數據合并發射
- switchOnNext( ) — 將一個發射Observables的Observable轉換成另一個Observable,后者發射這些Observables最近發射的數據
輔助操作符:用于Observable的輔助操作符
- materialize(?) — 將Observable轉換成一個通知列表convert an Observable into a list of Notifications
- dematerialize(?) — 將上面的結果逆轉回一個Observable
- timestamp(?) — 給Observable發射的每個數據項添加一個時間戳
- serialize(?) — 強制Observable按次序發射數據并且要求功能是完好的
- cache(?) — 記住Observable發射的數據序列并發射相同的數據序列給后續的訂閱者
- observeOn(?) — 指定觀察者觀察Observable的調度器
- subscribeOn(?) — 指定Observable執行任務的調度器
- doOnEach(?) — 注冊一個動作,對Observable發射的每個數據項使用
- doOnCompleted(?) — 注冊一個動作,對正常完成的Observable使用
- doOnError(?) — 注冊一個動作,對發生錯誤的Observable使用
- doOnTerminate(?) — 注冊一個動作,對完成的Observable使用,無論是否發生錯誤
- doOnSubscribe(?) — 注冊一個動作,在觀察者訂閱時使用
- doOnUnsubscribe(?) — 注冊一個動作,在觀察者取消訂閱時使用
- finallyDo(?) — 注冊一個動作,在Observable完成時使用
- delay(?) — 延時發射Observable的結果
- delaySubscription(?) — 延時處理訂閱請求
- timeInterval(?) — 定期發射數據
- using(?) — 創建一個只在Observable生命周期存在的資源
- single( ) — 強制返回單個數據,否則拋出異常
- singleOrDefault( ) — 如果Observable完成時返回了單個數據,就返回它,否則返回默認數據
- toFuture( ), toIterable( ), toList( ) — 將Observable轉換為其它對象或數據結構
還有一些 字符串處理、連接操作、算數據和操作等不再贅述。
這么多的東西你扔出來,你確定你不是在逗我?
客官息怒,這么多的操作符讓大家短時間內接受當然是不現實的,我們主要就是根據操作符的分類來學習一定類別的操作符是怎么使用的就可以了,需要使用的時候只需要到相應分類下去找到特定的操作符就好了。
以創建操作符為例:
在前面的例子中我們學習了如何使用最簡單的方式create來創建Observable對象
我們想要使用以前的例子依次打印 “hello”、”RXJAVA“、“this”、“is”、”a“、”demo“這幾個字符串我們該如何操作呢?
顯然我們應該這么做:
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello");
subscriber.onNext("RxJava");
subscriber.onNext("this");
subscriber.onNext("is");
subscriber.onNext("a");
subscriber.onNext("demo");
subscriber.onCompleted();
}
});
但是這樣的操作真的有必要嗎?RxJAVA中可以使用jsut和from創建操作符輕松完成上面的功能。
使用Just:
Observable observable=Observable
.just("hello","RxJava","this","is","a","demo");
使用from:
String infos[]={"hello","RxJava","this","is","a","demo"};
Observable observable=Observable.from(infos);
效果如下:
以變換操作符為例:
假設有這么一個場景根據若干數字數組求前一個遞歸和序列并轉換為string字符數組輸出。
如:1、2、3、4、5
輸出:[“1″,“3”,”6″,”10″,”15”]
Integer numbers[]={1,2,3,4,5,};
Observable observable=Observable.from(numbers);
observable
.scan(new Func2<Integer,Integer,Integer>() {
@Override
public Integer call(Integer sum, Integer item) {
return sum+item;
}
})
.map(new Func1<Integer,String>() {
@Override
public String call(Integer number) {
return String.valueOf(number);
}
})
.subscribe(subscriber);
首先我們使用From操作符創建Observable然后使用scan操作符來進行數據變換操作,然后我們使用map來進行數據格式變換操作來講int類型的數據轉換為String類型的數據。
scan操作符:
連續地對數據序列的每一項應用一個函數,然后連續發射結果
Scan操作符對原始Observable發射的第一項數據應用一個函數,然后將那個函數的結果作為自己的第一項數據發射。它將函數的結果同第二項數據一起填充給這個函數來產生它自己的第二項數據。它持續進行這個過程來產生剩余的數據序列。這個操作符在某些情況下被叫做accumulator。
Map操作符:
對Observable發射的每一項數據應用一個函數,執行變換操作
Map操作符對原始Observable發射的每一項數據應用一個你選擇的函數,然后返回一個發射這些結果的Observable。
Func,是RXJAVA中自帶接口函數(有返回值),從Func1到func9可以傳入多個參數,比如func1(String,String)第一個參數為傳入的參數類型第二個參數為返回值的類型。
Action1-Action9和Func類似,只不過Action是沒有返回值的。
以過濾操作為例:
情景:假設我們想要得到上述計算結果為偶數的字符數組呢?
在scan后增加過濾操作就ok了
.filter(new Func1<Integer,Boolean>() {
@Override
public Boolean call(Integer number) {
return (number%2==0);
}
})
那么符合條件的就只有6和10了
filter:發射通過過濾的數據,在func1中第一個參數為參數類型,第二個參數為boolean類型為返回值類型,返回true代表通過過濾,返回false代表過濾失敗,不會進行發射。
以結合操作符為例:
結合操作符可以讓Observables組合使用,下面以zip為例。
有三個不同的Observable為別獲取一個對象的size、color、shape,三者的數據類型可以任意定義。
我們可以使用zip操作符把三者獲取的屬性整合為具有三者屬性的一個對象。
Zip
通過一個函數將多個Observables的發射物結合到一起,基于這個函數的結果為每個結合體發射單個數據項。
Zip操作符返回一個Obversable,它使用這個函數按順序結合兩個或多個Observables發射的數據項,然后它發射這個函數返回的結果。它按照嚴格的順序應用這個函數。它只發射與發射數據項最少的那個Observable一樣多的數據。
RxJava將這個操作符實現為zip和zipWith。
zip的最后一個參數接受每個Observable發射的一項數據,返回被壓縮后的數據,它可以接受一到九個參數:一個Observable序列,或者一些發射Observable的Observables。
以輔助操作符為例:
在前面我們使用的線程調度例子中
observeOn(?) — 指定觀察者觀察Observable的調度器subscribeOn(?) — 指定Observable執行任務的調度器
都屬于輔助操作符,當然操作符有很多如:
delay(?) — 延時發射Observable的結果delaySubscription(?) — 延時處理訂閱請求
我們可以在以前的例子中使用這個操作符試驗下。
.delay(2,TimeUnit.SECONDS)//延遲兩秒發送
.delaySubscription(2,TimeUnit.SECONDS)//延遲兩秒訂閱
.subscribeOn(Schedulers.io())//調度器修改執行線程
.observeOn(AndroidSchedulers.mainThread())//修改執行線程
經過這樣的操作你就會發現結果會在4秒后開始顯示
當然RxJava的操作符有很多,我們不可能都掌握它,但是知道那些操作符屬于哪一類是很關鍵的,因為只有這樣你才可以更快的知道它的用法,在需要的時候快速地熟悉它掌握它。