RxJava操作符介紹,部分使用,使用場景,源碼淺析(二)

ReactiveX操作符

1. RxJava操作符介紹

創建操作
  • Create 從頭創建一個Observable
  • Defer 直到有觀察者訂閱時才創建Observable,并且為每個觀察者創建一個新的Observable
  • Empty/Never/Throw 創建行為受限的特殊Observable
    Empty 創建一個不發射任何數據但是正常終止的Observable
    Never 創建一個不發射數據也不終止的Observable
    Throw 創建一個不發射數據以一個錯誤終止的Observable
  • From 將其它對象或數據結構創建為Observable挨個發射
  • Interval 創建一個固定間隔發射整數序列的Observable,替代Timer
  • Just 創建一個發射指定值的Observable
  • Range 創建發射指定范圍的整數序列的Observable
  • Repeat 創建一個發射特定數據重復多次的Observable
  • Timer 創建在一個指定的延遲之后發射單個數據的Observable
變換操作(對Observable發射的數據進行變換)
  • Buffer 緩存,定期收集Observable的數據放進一個數據包裹,然后發射這些數據包裹,而不是一次發射一個值
  • FlatMap 將一個發射數據的Observable變換為多個Observables,然后將它們發射的數據合并后放進一個單獨的Observable
  • GroupBy 將原來的Observable分拆為Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據
  • Map 通過對序列的每一項都應用一個函數變換Observable發射的數據,實質是對序列中的每一項執行一個函數,函數的參數就是這個數據項
  • Scan 對Observable發射的每一項數據應用一個函數,然后按順序依次發射這些值
  • Window 定期將來自Observable的數據分拆成一些Observable窗口,然后發射這些窗口,而不是每次發射一項
過濾操作
  • Debounce 僅在過了一段指定的時間還沒發射數據時才發射一個數據
  • Distinct 過濾掉重復數據項
  • ElementAt 取特定位置的數據項
  • Filter 過濾掉函數返回false的數據項
  • First 只發射滿足條件的第一條數據
  • IgnoreElements 忽略所有的數據,只保留終止通知(onError或onCompleted)
  • Last 只發射最后一條數據
  • Sample 定期發射最新的數據,等于是數據抽樣,有的實現里叫ThrottleFirst
  • Skip 跳過前面的若干項數據
  • SkipLast 跳過后面的若干項數據
  • Take 只保留前面的若干項數據
  • TakeLast 只保留后面的若干項數據
組合操作
  • CombineLatest 當兩個Observables中的任何一個發射了數據時,使用一個函數結合每個Observable發射的最近數據項,并且基于這個函數的結果發射數據
  • Join 無論何時,如果一個Observable發射了一個數據項,只要在另一個Observable發射的數據項定義的時間窗口內,就將兩個Observable發射的數據合并發射
  • Merge 將兩個Observable發射的數據組合并成一個
  • StartWith 在發射原來的Observable的數據序列之前,先發射一個指定的數據序列或數據項
  • Switch 將一個發射多個Observables的Observable轉換成另一個單獨的Observable,如果Observable正在發射數據的時候,源Observable又發射出一個新的Observable,則前一個Observable發射的數據會被拋棄,直接發射新的Observable所發射的數據
  • Zip 通過一個函數將多個Observables的發射物結合到一起,基于這個函數的結果為每個結合體發射單個數據項。Zip操作符將多個Observable發射的數據按順序組合起來,每個數據只能組合一次,而且都是有序的。最終組合的數據的數量由發射數據最少的Observable來決定。
錯誤處理
  • Catch 繼續序列操作,將錯誤替換為正常的數據,從onError通知中恢復
  • Retry 如果Observable發射了一個錯誤通知,重新訂閱它,期待它正常終止。在發生錯誤的時候會重新進行訂閱,而且可以重復多次,所以發射的數據可能會產生重復。如果重復指定次數還有錯誤的話就會將錯誤返回給觀察者
    RetryWhen 指示Observable遇到錯誤時,將錯誤傳遞給另一個Observable來決定是否要重新給訂閱這個Observable,新Observable處理錯誤,老的繼續流程。
輔助操作
  • Delay 延遲一段時間發射結果數據
  • Do 注冊一個動作占用一些Observable的生命周期事件,相當于Mock某個操作,Do操作符就是給Observable的生命周期的各個階段加上一系列的回調監聽
  • Materialize/Dematerialize 將發射的數據和通知都當做數據發射,或者反過來
  • ObserveOn 指定觀察者觀察Observable的調度程序(工作線程)
  • Serialize 強制Observable按次序發射數據并且功能是有效的
  • Subscribe 收到Observable發射的數據和通知后執行的操作
  • SubscribeOn 指定Observable應該在哪個調度程序上執行
  • TimeInterval 將一個Observable轉換為發射兩個數據之間所耗費時間的Observable
  • Timeout 添加超時機制,如果過了指定的一段時間沒有發射數據,就發射一個錯誤通知
  • Timestamp 給Observable發射的每個數據項添加一個時間戳
  • Using 創建一個只在Observable的生命周期內存在的一次性資源
    我們創建一個資源并使用它,用一個Observable來限制這個資源的使用時間,當這個Observable終止的時候,這個資源就會被銷毀。
條件和布爾操作
  • All 判斷Observable發射的所有的數據項是否都滿足某個條件
  • Amb 給定多個Observable,只讓第一個發射數據的Observable發射,將至多9個Observable結合起來,讓他們競爭。哪個Observable首先發射了數據(包括onError和onComplete)就會繼續發射這個Observable的數據,其他的Observable所發射的數據都會被丟棄。
  • Contains 判斷Observable是否會發射一個指定的數據項,如果源Observable已經結束了卻還沒有發射這個數據則返回false
  • IsEmpty操作符用來判斷源Observable是否發射過數據,如果發射過就會返回false,如果源Observable已經結束了卻還沒有發射這個數據則返回true。
  • DefaultIfEmpty 發射來自原始Observable的數據,如果原始Observable沒有發射數據,就發射一個默認數據
  • SequenceEqual 判斷兩個Observable是否按相同的數據序列
  • SkipUntil 丟棄原始Observable發射的數據,直到標志的Observable發射了一個數據,然后發射原始Observable的剩余數據
  • SkipWhile 丟棄原始Observable發射的數據,直到一個特定的條件為假,然后發射原始Observable剩余的數據
  • TakeUntil 發射來自原始Observable的數據,直到標志的Observable發射了一個數據,然后跳過剩余的數據
  • TakeWhile 發射原始Observable的數據,直到一個特定的條件為真,然后跳過剩余的數據
算術和聚合操作
  • Average 計算Observable發射的數據序列的平均值,然后發射這個結果
  • Concat 不交錯的連接多個Observable的數據
    將多個Observable結合成一個Observable并發射數據,并且嚴格按照先后順序發射數據,前一個Observable的數據沒有發射完,是不能發射后面Observable的數據的。
  • Count 計算Observable發射的數據個數,然后發射這個結果
    如果源Observable發射錯誤,則會將錯誤直接報出來;在源Observable沒有終止前,count是不會發射統計數據的。
  • Max 計算并發射數據序列的最大值
  • Min計算并發射數據序列的最小值
  • Reduce 按順序對數據序列的每一個應用某個函數,然后返回這個值
    接收Observable發射的數據和函數的計算結果作為下次計算的參數,輸出最后的結果。
  • Sum 計算并發射數據序列的和
連接操作
  • Connect 指示一個可連接的Observable開始發射數據給訂閱者
  • Publish 將一個普通的Observable轉換為可連接的
  • RefCount 使一個可連接的Observable表現得像一個普通的Observable
  • Replay 確保所有的觀察者收到同樣的數據序列,即使他們在Observable開始發射數據之后才訂閱
自定義操作符
  • lift 如果我們的自定義操作符想要作用到Observable發射出來的數據上,使用lift操作符
  • compose 如果我們的自定義操作符想要改變整個的Observable,使用compose操作符

2. RxJava操作符的使用

RxJava操作符的使用

3. lift源碼解析

1.先看看Observablecreate()

public static <T> Observable<T> create(OnSubscribe<T> f) {
    return new Observable<T>(RxJavaHooks.onCreate(f));
}

Observable的構造方法

protected Observable(OnSubscribe<T> f) {
    this.onSubscribe = f;
}

RxJavaHooksonCreate()方法

public static <T> Observable.OnSubscribe<T> onCreate(Observable.OnSubscribe<T> onSubscribe) {
    Func1<OnSubscribe, OnSubscribe> f = onObservableCreate;
    if (f != null) {
        return f.call(onSubscribe);
    }
    return onSubscribe;
}

hook了Observable.OnSubscribe

2.在看Observablelift()

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
    return create(new OnSubscribeLift<T, R>(onSubscribe, operator));
}

OnSubscribeLift

public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {
    final OnSubscribe<T> parent;
    final Operator<? extends R, ? super T> operator;
    public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
    this.parent = parent;
    this.operator = operator;
    }
    @Override
    public void call(Subscriber<? super R> o) {
        try {
            Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
            try {
                st.onStart();
                parent.call(st);
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                st.onError(e);
            }
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            o.onError(e);
        }
    }
}

RxJavaHooksonObservableLift()方法

public static <T, R> Operator<R, T> onObservableLift(Operator<R, T> operator) {
    Func1<Operator, Operator> f = onObservableLift;
    if (f != null) {
        return f.call(operator);
    }
    return operator;
}

同樣hook了Observable.OnSubscribe,是新的onSubscribe
這里的parent就是舊onSubscribe
總結下,新的Observable會像一個代理一樣,負責接收原始的Observable發出的事件,并在處理后發送給Subscriber

4. RxJava應用場景

  • 取數據先檢查緩存的場景
  • 界面需要等到多個接口并發取完數據,再更新merge
  • 一個接口的請求依賴另一個API請求返回的數據
  • 界面按鈕需要防止連續點擊的情況throttleFirst
  • 響應式的界面checkedChanges
  • 復雜的數據變換
  • 輪詢
  • 線程切換
  • RxBus
  • RxBinding Android控件對RxJava的支持庫
  • rx-preferences 使SharedPreferences支持 RxJava
  • RxLifecycle 幫助RxJava在Android中生命周期的控制,避免內存溢出等問題
  • retrofit Retrofit
  • storio 數據庫對RxJava的支持
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本篇文章介主要紹RxJava中操作符是以函數作為基本單位,與響應式編程作為結合使用的,對什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,890評論 0 10
  • 創建操作 用于創建Observable的操作符Create通過調用觀察者的方法從頭創建一個ObservableEm...
    rkua閱讀 1,867評論 0 1
  • RxJava正在Android開發者中變的越來越流行。唯一的問題就是上手不容易,尤其是大部分人之前都是使用命令式編...
    劉啟敏閱讀 1,922評論 1 7
  • 作者: maplejaw本篇只解析標準包中的操作符。對于擴展包,由于使用率較低,如有需求,請讀者自行查閱文檔。 創...
    maplejaw_閱讀 45,808評論 8 93
  • 注:只包含標準包中的操作符,用于個人學習及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,230評論 2 8