RxJava2學習筆記對應的xmind圖片

在這裏插入圖片描述

RxJava2

Rx介紹

Rx是一個函數庫,讓開發者可以利用可觀察序列和LINQ風格查詢操作符來編寫異步和基於事件的程序,使用Rx,開發者可以用Observables表示異步數據流,用LINQ操作符查詢異步數據流,用Scheduler參數化異步數據流的併發處理。

     Rx可以這樣定義:Rx = Observables + LINQ + Schedulers

    官方定義:Rx是一個使用可觀察數據流進行異步編程的編程接口,Rx結合了觀察者模式、迭代器模式和函數式編程的精華。
  • Q1:什麼是LINQ風格?
    a) LINQ是另外一種數據抽象層;
    b) LINQ是所有類型數據的統一編程模型,它可以讓你使用一致的模型查詢和使用數據,而不用關心數據源是什麼。
  • Q2 : 迭代器模式?
    迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據。
  • Q3 :函數式編程?
    函數式編程關心類型(代數結構)之間的關係,命令式編程關心解決問題的步驟

相關學習地址

ReactiveX文檔中文翻譯

github首頁

通過gradle引入

(其中x和y表示最新版本號)

compile “io.reactivex.rxjava2:rxjava:2.x.y”
github鏈接:https://github.com/ReactiveX/RxJava

官方例子

入門使用

  • Flowable.just(“Hello world!”)
    .subscribe(new Consumer(){
    @Override
    public void accept(String s){
    System.out.println(s);
    }
    });

在後臺線程上運行一些計算和網絡請求

並在UI線程上顯示結果(或錯誤)

  • Flowable.fromCallable(()->{
    Thread.sleep(“1000”); //模擬耗時操作
    return “Done”;
    })
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.single())
    .subscribe(System.out::println,Throwable::printStackTrace);

    這種方法調用我們稱之爲鏈式調用(fluent API),類似於構建者模式。但是RxJava的響應式返回類型是不變的;每一次的方法調用都只會返回一個新的具有可添加行爲的Flowable對象。爲了驗證這一點,以上方法可以被改寫爲:
    Flowable source;
    Flowable runBackground;
    Flowable showForeground;

    source=Flowable.formCallable(() ->{
    Thread.sleep(1000);
    return “Done”;
    });

    runBackground=source
    .subscribeOn(Schedulers.io());

    showForeground=runBackgounrd
    .observeOn(Schedulers.single());

    showForeground
    .subscribe(System.out::println, Throwable::printStackTrace)

一些術語

Reactive

  • 直譯爲反應性的,有活性的,根據上下文一般翻譯爲反應式、響應式

Iterable

  • 可迭代對象,支持以迭代器的形式遍歷,許多語言中都存在這個概念

Observable

  • 可觀察對象,在Rx中定義爲更強大的Iterable,在觀察者模式中是被觀察的對象,一旦數據產生或發生變化,會通過某種方式通知觀察者或訂閱者

Observer

  • 觀察者對象,監聽Observable發射的數據並做出響應,Subscriber是它的一個特殊實現

emit

  • 直譯爲發射,發佈,發出,含義是Observable在數據產生或變化時發送通知給Observer,調用Observer對應的方法,文章裏一律譯爲發射

items

  • 譯爲項目,條目,在Rx裏是指Observable發射的數據項,文章裏一律譯爲數據,數據項

backpressure

    背壓
  •   數據流發射,處理,響應可能在各自的線程中獨立進行,上游在發射數據的時候,不知道下游是否處理完,也不會等下游處理完之後再發射。
    

這樣,如果上游發射的很快而下游處理的很慢,會怎樣呢?

   數據流通過異步步驟運行時,這種情況將會產生很多下游沒來得及處理的數據,這些數據既不會丟失,也不會被垃圾回收機制回收,而是存放在一個異步緩存池中,如果緩存池中的數據一直得不到處理,越積越多,最後就會造成內存溢出,這便是Rxjava中的背壓問題。

    在RxJava中,專用Flowable類指定支持背壓,Observable專門用於非背壓操作(短序列、GUI交互等)。其它類型Single,Maybe和Completable不支持背壓,也不應該支持背壓,總是有空間暫時存放一個item項目

Upstream,downStream

     上游和下游
  •    RxJava中的數據流包括一個源、0個或多箇中間步驟,後跟
    

數據使用者或組合步驟(其中該步驟負責通過某種方式使用數據流)
例子:
source.operator1().operator2().operator3().subscribe(consumer);
( operator1是operator2的上游,operator3是operator2的下游,表達了用戶/消費者的權利 )

Objects in motion

       運動中的對象
      在RxJava的文檔中,發射(emission),發射(emit),項目(item),事件(event),信號(signal),數據(data)和消息(message)被認爲是同義詞,並代表沿着數據流傳播的對象。

“冷”與“熱”

  •       從Observable什麼時候開始發射數據序列上看:
        冷的Observable  ->  等待訂閱纔開開始發射數據   
        熱的Observable  ->  無需等待訂閱,直接發射item
    

一些關鍵類

簡介

  •  Flowable是爲了解決背壓(backpressure)問題的
    

a) Flowable是Publisher與Subscriber這一觀察者模式中Publisher的典型實現
b) Observable是ObservableSource/Observer這一組觀察者模式中ObservableSource的典型實現;

  •     一個可觀察對象(Observable),觀察者(Observer)訂閱(Subscribe)它,當數據就緒時,之前定義的機制就會分發數據給一直處於等待狀態的觀察者哨兵。
    
  •     Single類似於Observable,不同的是,它總是隻發射一個值,或者一個錯誤通知,而不是發射一系列的值。
    
         因此,不同於Observable需要三個方法onNext, onError, onCompleted,訂閱Single只需要兩個方法:
    
        onSuccess - Single發射單個的值到這個方法
        onError - 如果無法發射需要的值,Single發射一個Throwable對象到這個方法
        Single只會調用這兩個方法中的一個,而且只會調用一次,調用了任何一個方法之後,訂閱關係終止..
    
  • Intenationnal chool

      一個橋樑或者代理,同時充當了Observer和Observable的角色。即它可以訂閱一個或者多個的Observable也可以轉發它收到的數據或者發射新的數據
            
       一共有四種類型Subject:
    

a)AsyncSubject :
只在原始Observable完成後,發射來自原始Observable的最後一個值。它會把這最後一個值發射給任何後續的觀察者。

b)BehaviorSubject:
當觀察者訂閱BehaviorSubject時,它開始發射原始Observable最近發射的數據,然後繼續發射其它任何來自原始Observable的數據.

c)PublishSubject::
只會把訂閱發生的時間點之後的來自原始Observable的數據發射給觀察者。需要注意的是它可能會一創建完成就立刻開始發射數據,有風險存在:在Subject被創建後到有觀察者訂閱它之前的這個時間段內,一個或者多個數據可能會丟失,

d)ReplaySubject:
會發射所有來自原始Observable的數據給觀察者,無論它們是何時訂閱的。注意:用作一個觀察者時,注意不要從多個線程中調用它的onNext等等系列,這可能導致同時(非順序)調用,這會違反Observable協議,給Subject的結果增加了不確定性。

Rx模式

使用觀察者模式

  • 創建:Rx可以方便地創建事件流和數據流
  • 組合:Rx使用查詢式的操作符組合變換數據流
  • 監聽:Rx可以訂閱任何可觀察的數據流並執行操作

簡化代碼

  • 函數式風格:
    對可觀察數據流使用無副作用的輸入輸出函數,
    避免了程序裏錯綜複雜的狀態
  • 簡化代碼:
    Rx的操作符通常可以將複雜的難題簡化爲很少的幾行代碼
  • 異步錯誤處理:
    傳統的try/catch沒辦法處理異步計算,Rx提供了合適的錯誤
    處理機制
  • 輕鬆使用併發:
    Rx的Observables和Schedulers讓開發者可以擺脫底層的線程
    同步和各種併發問題

operator操作符

創建操作

  • create

    • 使用一個函數從頭開始創建一個Observable
      create方法默認不在任何特定的調度器上執行
  • Defer

    • 直到有觀察者訂閱時才創建Observable,並且爲每個觀察者創建一個新的Observable,即每個訂閱者獲取的是專屬的單獨的數據序列
  • Empty/Never/Throw

    • Empty:創建一個不發射任何數據但是正常終止的Observable
      Never: 創建一個不發射數據也不終止的Observable
      Throw: 創建一個不發射數據以一個錯誤終止的Observable.
      總結: 測試的時候很有用
  • From

    • 將其它種類的對象和數據類型轉換爲Observable
      在RxJava中,from操作符可以轉換Future、Iterable和數組
  • Interval

    • 創建一個按固定時間間隔發射整數序列的Observable
  • Just

    • 創建一個發射指定值的Observable
  • Range

    • 創建一個發射特定整數序列的Observable
  • Repeat

    • 創建一個發射特定數據重複多次的Observable
  • Start

    • 返回一個Observable,它發射一個類似於函數聲明的值
  • Timer

    • 創建一個Observable,它在一個給定的延遲後發射一個特殊的值。
      Observable.timer(2, TimeUnit.SECONDS); //間隔2s發射

變換操作

  • Buffer

    • 定期收集Observable的數據放進一個數據包裹,然後發射這些數據包裹,而不是一次發射一個值,RxJava中有許多Buffer的變體
  • FlatMap

    •     將一個發射數據的Observable變換爲多個Observables,然後將它們發射的數據合併後放進一個單獨的Observable
      
      FlatMap操作符使用一個指定的函數對原始Observable發射的每一項數據執行變換操作,這個函數這個函數返回一個本身也發射數據的Observable,然後FlatMap合併這些Observables發射的數據,最後將合併後的結果當做它自己的數據序列發射。
  • GroupBy

    • 將一個Observable分拆爲一些Observables集合,它們中的每一個發射原始Observable的一個子序列
  • Map

    • 對Observable發射的每一項數據應用一個函數,執行變換操作
  • Scan

    • 連續地對數據序列的每一項應用一個函數,然後連續發射結果
  • Window

    • 定期將來自原始Observable的數據分界爲一個Observable窗口,發射這些窗口,而不是每次發射一項數據

過濾操作

  • Debounce

    • 僅在過了一段指定的時間還沒發射數據時才發射一個數據
  • Distinct

    • 抑制(過濾掉)重複的數據項
  • ElementAt

    • 只發射第N項數據
  • Filter

    • 只發射通過了謂詞測試的數據項
  • First

    • 只發射第一項(或者滿足某個條件的第一項)數據
  • IgnoreElements

    • 不發射任何數據,只發射Observable的終止通知
  • Last

    • 只發射最後一項(或者滿足某個條件的最後一項)數據
  • Sample

    • 定期發射Observable最近發射的數據項
  • Skip

    • 抑制Observable發射的前N項數據
  • SkipLast

    • 抑制Observable發射的後N項數據
  • Take

    • 只發射前面的N項數據
  • TakeLast

    • 發射Observable發射的最後N項數據

結合操作

  • And/Then/When

    • 使用Pattern和Plan作爲中介,將兩個或多個Observable發射的數據集合併到一起
  • CombineLatest

    • 當兩個Observables中的任何一個發射了數據時,使用一個函數結合每個Observable發射的最近數據項,並且基於這個函數的結果發射數據。
  • Join

    • 任何時候,只要在另一個Observable發射的數據定義的時間窗口內,這個Observable發射了一條數據,就結合兩個Observable發射的數據。
  • Merge

    • 合併多個Observables的發射物
  • StartWith

    • 在數據序列的開頭插入一條指定的項
  • Switch

    • 將一個發射多個Observables的Observable轉換成另一個單獨的Observable,後者發射那些Observables最近發射的數據項
  • Zip

    • 通過一個函數將多個Observables的發射物結合到一起,基於這個函數的結果爲每個結合體發射單個數據項。

錯誤處理

  • Catch

    • Catch操作符攔截原始Observable的onError通知,將它替換爲其它的數據項或數據序列,讓產生的Observable能夠正常終止或者根本不終止。
  • Retry

    • 如果原始Observable遇到錯誤,重新訂閱它期望它能正常終止

輔助操作

  • Delay

    • 延遲一段指定的時間再發射來自Observable的發射物
  • Do

    • 註冊一個動作作爲原始Observable生命週期事件的一種佔位符
  • Materialize/Dematerialize

    • Materialize將數據項和事件通知都當做數據項發射,Dematerialize剛好相反
  • ObserveOn

    • 指定一個觀察者在哪個調度器上觀察這個Observable
  • Serialize

    • 強制一個Observable連續調用並保證行爲正確
  • Subscribe

    • 操作來自Observable的發射物和通知
  • SubscribeOn

    • 指定Observable自身在哪個調度器上執行
  • TimeInterval

    • 將一個發射數據的Observable轉換爲發射那些數據發射時間間隔的Observable
  • Timeout

    • 對原始Observable的一個鏡像,如果過了一個指定的時長仍沒有發射數據,它會發一個錯誤通知
  • Timestamp

    • 給Observable發射的數據項附加一個時間戳
  • Using

    • 創建一個只在Observable生命週期內存在的一次性資源
  • To

    • 將Observable轉換爲另一個對象或數據結構

條件和布爾操作

  • All/Contains/Amb
  • DefaultEmpty
  • SequenceEqual
  • SkipUntil/SkipWhile
  • TakeUntil/TakeWhile

算術和聚合操作

  • Average/Concat/Reduce

  • Max/Min/Count/Sum

連接操作

  • Connect

關注Fragment和Activity的生命週期

  在Android上,要在異步操作中訪問框架中的對象有些棘手,那是因爲Andoid系統可以決定銷燬(destroy)一個 Activity,例如,當一個後臺線程還在運行的時候,如果這個線程嘗試訪問一個已經死掉的Activity中的View對象,會導致異常退出(Crash)。(這也會導致內存泄露,因爲 Activity 已經不可見了,你的後臺線程還持有它的引用。)


   這仍然是在Android上使用RxJava需要關注的一個問題,但是通過使用 Subscription和其它Observable操作符,你可以優雅地解決這個問題。通常來說,當你在Activity中訂閱一個Observable的結果時(無論是直接的還是通過一個內部類),你必須在 onDestroy 裏取消訂閱,就像下面例子裏展示的那樣:(可以考慮使用Rxlifecycle自動防止內存泄漏問題)
MyActivityprivate Subscription subscription;

protected void onCreate(Bundle savedInstanceState) {
    this.subscription = observable.subscribe(this);
}
protected void onDestroy() {
    this.subscription.unsubscribe();
    super.onDestroy();
}

RxAndroid

RxJava2 的Android特定綁定。它將最小類添加到RxJava中,這使得在Android中編寫響應式組件變得簡單而輕鬆。具體地說,它提供了一個Scheduler調度器,專門用於UI線程即主線程或者是給定的任意Looper

封裝

維護一個全局單例的Retrofit對象

OkhttpClient統一添加請求參數或者請求頭

對於返回的gson數據除Data域不同其它一致,對返回結果POJO對象做一次封裝,用泛型替換不定的數據域部分

用compose替換重複的模板代碼

對於錯誤的統一處理可以考慮用compose

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