簡單來說RxJava是一個實現響應式程式設計的類庫。
那什麼是響應式程式設計?
響應式程式設計的核心思想是"資料流是第一等公民”,程式的邏輯建立在資料流的變化之上。
響應式程式設計的幾個核心概念:
(1)資料流:在響應式程式設計中,資料以流(Streans)的形式存在。流就像一條河,源源不斷。比如一個陣列或集合可以看作一個資料流,陣列或集合中的每個元素視為資料流中的資料項。
(2)非同步處理:傳統的同步程式設計模型中,當執行一個耗時的操作時,主執行緒會被阻塞,直到操作完成才能繼續執行後續的程式碼。這種模型存在一個問題,即當一個操作耗時很長,主執行緒被阻塞時,整個應用程式就會感覺不夠靈活和響應遲緩。
響應式程式設計則透過非同步處理來解決這個問題。在響應式程式設計中,當需要執行一個可能耗時的操作時,不會讓主執行緒直接等待其完成。相反,這個操作會被放到一個單獨的執行執行緒(通常是執行緒池中的一個執行緒)中去執行,同時主執行緒可以繼續執行其他任務而不被阻塞。一旦非同步操作完成,會透過回撥函式、觀察者模式或者其他機制通知應用程式,以便在未來某個時間點處理操作結果。
(3)變化傳播:當資料來源發生變化時,響應式程式設計模型會自動將變化傳播到依賴這些資料來源的地方。這種傳播是自動的,不需要顯式呼叫。
什麼是RxJava?
Rxlava是基於觀察者模式實現的,分別有觀察者和被觀察者兩個角色,被觀察者會實時傳輸資料流,觀察者可以觀測到這些資料流。基於傳輸和觀察的過程,使用者可以透過一些操作方法對資料進行轉換或其他處理。在RxJava中,觀察者就是Observer,被觀察者是Observable和Flowable。
Observable適合處理相對較小的、可控的、不會迅速產生大量資料的場景。它不具備背壓處理能力,也就是說,當資料生產速度超過資料消費速度時,可能會導致記憶體溢位或其他效能問題。
Fowable是針對背壓(反向壓力)問題而設計的可觀測型別。背壓問題出現於資料生產速度超過資料消費速度的場景。Flowable 提供了多種背壓策略來處理這種情況,確保系統在處理大量資料時仍然能夠保持穩定。
被觀察者. subscribe(觀察者),它們之間就會建立訂閱關係,被觀察者傳輸的資料或者發出的事件會被觀察者觀察到。
前面提到使用者可以透過一些方法對資料進行轉換或其他處理,RxJava提供了很多運算子供我們使用,這塊其實和Java8的Stream類似,概念上都是一樣的。
運算子主要可以分為以下幾大類:
變換類運算子,對資料流進行變換,如map、flatMap 等。比如利用map將int型別轉為string
Flowable<String> flowable = Flowable.range(0,Integer.MAX_VALUE)
.map(i->String.valueOf(i))
聚合類運算子,對資料流進行聚合,如toList、toMap等
Flowable.range(0,Integer.MAX_VALUE).toList()
過濾運算子,過濾或者跳過一些運算子,如fliter、skip等
Flowable.range(0,Integer.MAX_VALUE).fliter(i->i>10).toList();
連線運算子,將多個資料流連線到一起,如concat、zip等
//建立兩個Flowable,透過concat連線得到一個被觀察者,進行統一處理
//建立兩個Flowable 物件
Flowable<String> flowable1 = Flowable.just( "A","B","C");
Flowable<String> flowable2 = Flowable.just("D","E","F");
//使用concat運算子將兩個Flowable合併
Flowable<String> flowable = Flowable.concat(flowable1,flowable2);
排序運算子,對資料流內的資料進行排序,如sorted
Flowable<String> flowable = Flowable.concat(flowable1,flowable2).sorted();
RxJava也是一個基於事件驅動的框架,我們來看看一共有哪些事件,分別在什麼時候觸發:
- onNext,被觀察者每傳送一次資料,就會觸發此事件。
- onError,如果傳送資料過程中產生意料之外的錯誤,那麼被觀察者可以傳送此事件。
- onComplete,如果沒有發生錯誤,那麼被觀察者在最後一次呼叫onNext,之後傳送此事件表示完成資料傳輸。對應的觀察者得到這些事件後,可以進行一定處理,例如:
flowable.observeon( Schedulers.io())
.doOnNext( item -> {
System.out.println("來資料啦"+ item.toString());})
.doOnError(e -> {
system.out.println("出錯啦"+e.getMessage( ));})
.doonComplete(( ->{
system.out.println("資料處理完啦");}).subscribe();