版權所有,轉載請註明出處:linzhiyong https://blog.csdn.net/u012527802/article/details/81117684 https://www.jianshu.com/p/559c5e7376a2
本文主要介紹RxJava2是什麼、RxJava2的基本使用。
Github:https://github.com/ReactiveX/RxJava
RxDoc:http://reactivex.io/RxJava/2.x/javadoc/
RxJava2Demo:https://github.com/linzhiyong/RxJava2Demo
目錄
1. RxJava2介紹
1.1 什麼是RxJava
Github的介紹
RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.
It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.
Google翻譯一下
RxJava是一個在Java虛擬機上的響應式擴展:一個用於通過使用可觀察序列來編寫異步和基於事件的程序的庫。
它擴展了觀察者模式以支持數據/事件序列,並添加了允許您以聲明方式組合序列的運算符,同時抽象出對低級線程,同步,線程安全和併發數據結構等問題的關注。
總結一下,RxJava是基於響應式編程思想,實現並擴展了觀察者模式,可以進行異步操作的庫。
注:這裏簡單介紹一下,響應式編程、觀察者模式的概念
1、響應式編程,簡稱RP(Reactive Programming),是一個專注於數據流和變化傳遞的異步編程範式。一個簡單的例子:在Excel中,在A1單元格輸入數字,在B1輸入數字,設置C1的內容爲SUM(A1, B1),一旦A1或B1數值變化,那麼C1將會立即更新;
2、觀察者模式,屬於行爲型模式,又叫發佈-訂閱(Publish/Subscribe)模式、模型-視圖 (Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式,作用是定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。例如:拍賣的時候,拍賣師觀察最高標價,然後通知給其他競價者競價。
1.2 RxJava2與RxJava區別
1、在Rxjava 2中,有一個新的Reactive類型:Flowable,它與Observable很相似,但是有一個關鍵的不同是,Flowable支持背壓 backpressure。支持backpressure,如果事件的消費者不能及時消費生產的事件時可以定義一個處理事件的策略,開發者要自己實現這個事件處理策略。[關於背壓];
2、Rxjava2中onNext設計成限制不能傳null;
/**
* Signal a normal value.
* @param value the value to signal, not null
*/
void onNext(@NonNull T value);
3、增加Single角色,和Observable,Flowable一樣會發送數據,不同的是訂閱後只能接受到一次;
4、Actions和Functions方法名的修改和次要類的刪除;
5、。。。
1.3 RxJava2的角色和事件介紹
角色 | 功能 |
---|---|
被觀察者(Observable/Flowable) | 產生事件(Flowable支持背壓) |
觀察者(Observer/Subscriber) | 響應事件並做出處理 |
事件(event) | 被觀察者和觀察者的消息載體 |
訂閱(subscribe) | 關聯被觀察者和觀察者 |
訂閱控制(Disposable/Subscription) | 用於取消被觀察者與觀察者的關係,Subscription支持背壓拉取消息 |
RxJava2事件消費者包括Observer、Subscriber、Consumer。其中使用Consumer的話,RxJava內部默認實現Observer/Subscriber,然後在onNext()方法中回調Consumer的accept()。
下面主要介紹一下Emitter、Observer/Subscriber,Emitter接口作爲被觀察者的事件發射器,有3中事件:onNext、onError、onComplete;Observer/Subscriber作爲觀察者的事件接收器,兩個接口除了名字完全相同,只是爲了區分Observable/Flowable的使用,包含4種事件:onSubscribe、onNext、onError、onComplete;
事件 | 說明 |
---|---|
onSubscribe | 觀察者訂閱被觀察者時,觸發該事件,同時返回一個訂閱控制對象(Disposable/Subscription) |
onNext | 被觀察者通過onNext可以發送多個事件,觀察者可以通過onNext接收多個事件 |
onError | 被觀察者發送onError事件後,其他事件被終止發送,觀察者收到onError事件後會終止接受其他事件 |
onComplete | 被觀察者發送onComplete事件後,其他事件被終止發送,觀察者收到onComplete事件後會終止接受其他事件 |
注:onError和onComplete是互斥的事件,一個正確運行的事件序列中, onCompleted和onError只能有一個,並且是事件序列中的最後一個。
看一個訂閱的示例
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 使用Emitter事件發射器發射事件
emitter.onNext("這是事件1");
emitter.onNext("這是事件2");
// emitter.onError(new Exception("這裏事件發生了異常。"));
emitter.onNext("這是事件3");
emitter.onNext("這是事件4");
emitter.onComplete();
}
});
// 定義觀察者,接收事件
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// 訂閱成功回調該方法,返回控制對象
// d.dispose();
Log.i(TAG, "--onSubscribe--");
}
@Override
public void onNext(String s) {
// 這裏接收被觀察者發出的事件
Log.i(TAG, "--onNext--" + s);
}
@Override
public void onError(Throwable e) {
// 錯誤事件
Log.i(TAG, "--onError--" + e.getMessage());
}
@Override
public void onComplete() {
// 完成事件
Log.i(TAG, "--onComplete--");
}
};
// 觀察者訂閱被觀察者
observable.subscribe(observer);
}
看一下控制檯日誌:
I/com.lzy.org.rxjava2.RxJava2Test2: --onSubscribe--
I/com.lzy.org.rxjava2.RxJava2Test2: --onNext--這是事件1
I/com.lzy.org.rxjava2.RxJava2Test2: --onNext--這是事件2
I/com.lzy.org.rxjava2.RxJava2Test2: --onNext--這是事件3
I/com.lzy.org.rxjava2.RxJava2Test2: --onNext--這是事件4
I/com.lzy.org.rxjava2.RxJava2Test2: --onComplete--
2 RxJava2常用操作符介紹
2.1 創建操作符
名稱 | 功能介紹 |
---|---|
create | public static Observable create(ObservableOnSubscribe source) 創建一個被觀察者,同時定義併發送事件,手動維護事件的發送和結束 |
just | public static Observable just(T item1, … T item10) 創建一個被觀察者,併發送事件,發送的事件不可以超過10個 |
fromArray | public static Observable fromArray(T… items) 創建一個被觀察者,併發送事件,參數接收一個事件數組 |
fromIterable | public static Observable fromIterable(Iterable source) 創建一個被觀察者,併發送事件,參數接收一個事件集合,如List |
fromCallable | public static Observable fromCallable(Callable supplier) 參數Callable 是 java.util.concurrent 中的 Callable,Callable 和 Runnable 的用法基本一致,只是它會返回一個結果值,這個結果值就是發給觀察者的 |
fromFuture | public static Observable fromFuture(Future future) 參數中的 Future 是 java.util.concurrent 中的 Future,Future 的作用是增加了 cancel() 等方法操作 Callable,可以通過 get() 方法來獲取 Callable 返回的值 |
defer | public static Observable defer(Callable> supplier) 只有觀察者訂閱的時候纔會創建新的被觀察者,所以每訂閱一次就會通知一次觀察者 |
timer | public static Observable timer(long delay, TimeUnit unit) 延時發送,當到指定時間後就會發送一個 0L 的值給觀察者 |
interval | public static Observable interval(long period, TimeUnit unit) public static Observable interval(long period, TimeUnit unit, Scheduler scheduler) 定時發送,每隔一段時間就會發送一個事件,這個事件從0開始遞增 |
intervalRange | public static Observable intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit) 可以指定發送事件的開始值和發送數量,其他與 interval() 的功能一樣 |
range/rangeLong | public static Observable range(final int start, final int count) public static Observable rangeLong(long start, long count) 發送一定範圍的事件序列 |
2.2 線程相關操作符
名稱 | 功能介紹 |
---|---|
subscribeOn | public final Single subscribeOn(final Scheduler scheduler) 指定被觀察者事件發送的線程,如果多次調用此方法,只有第一次有效 |
observeOn | public final Observable observeOn(Scheduler scheduler) 指定觀察者處理事件的線程,每指定一次就會生效一次 |
注:Scheduler類型
類型 | 使用方式 | 含義 | 使用場景 |
---|---|---|---|
IoScheduler | Schedulers.io() | io操作線程 | 讀寫SD卡文件、查詢數據庫、訪問網絡等IO密集型等操作 |
NewThreadScheduler | Schedulers.newThread() | 創建新線程 | 耗時操作等 |
SingleScheduler | Schedulers.single() | 單例線程 | 只需一個單例線程時 |
ComputationScheduler | Schedulers.computation() | CPU計算操作線程 | 圖片壓縮取樣、xml、json解析等CPU密集型計算 |
TrampolineScheduler | Schedulers.trampoline() | 當前線程 | 需要在當前線程立即執行任務時 |
HandlerScheduler | AndroidSchedulers.mainThread() | Android主線程 | 更新U等I |
ExecutorScheduler | Schedulers.from(Executor executor) | 自定義線程 | 自定義任務等 |
2.3 事件監聽操作符
名稱 | 功能介紹 |
---|---|
doOnNext | public final Observable doOnNext(Consumer onNext) 每次發送onNext之前回調 |
doOnEach | public final Observable doOnEach(final Observer observer) 每次發送事件之前回調 |
doAfterNext | public final Observable doAfterNext(Consumer onAfterNext) 每次發送onNext事件之後回調 |
doOnError | public final Observable doOnError(Consumer onError) 發送 onError() 之前回調 |
doOnComplete | public final Observable doOnComplete(Action onComplete) 發送 onComplete() 之前回調 |
doOnSubscribe | public final Observable doOnSubscribe(Consumer onSubscribe) 發送 onSubscribe() 之前回調 |
doOnDispose | public final Observable doOnDispose(Action onDispose) 調用 Disposable 的 dispose() 之後回調 |
doOnTerminate doAfterTerminate |
doOnTerminate 是在 onError 或者 onComplete 發送之前回調,而 doAfterTerminate 則是 onError 或者 onComplete 發送之後回調(取消訂閱,方法失效) |
doFinally | public final Observable doFinally(Action onFinally) 無論是否取消訂閱,在所有事件發送完畢之後回調該 |
2.4 過濾操作符
名稱 | 功能介紹 |
---|---|
filter | public final Flowable filter(Predicate predicate) 通過一定的邏輯來過濾被觀察者發送的事件,返回 true 則發送事件,否則不發送 |
ofType | public final Observable ofType(final Class clazz) 事件類型過濾 |
distinct | public final Observable distinct() 去重操作符,去掉重複的事件 |
distinctUntilChanged | public final Observable distinctUntilChanged() 過濾掉連續重複的事件 |
skip | public final Observable skip(long count) 跳過世界集合中的某些事件,count 代表跳過事件的數量 |
debounce | public final Observable debounce(long timeout, TimeUnit unit) 如果兩件事件發送的時間間隔小於設定的時間間隔timeout,則前一件事件就不會發送 |
take | public final Observable take(long count) 取指定數量的事件 |
firstElement / lastElement | public final Maybe firstElement() firstElement() 獲取事件序列的第1個元素,lastElement() 獲取事件序列的最後1個元素 |
elementAt / elementAtOrError | public final Maybe elementAt(long index) elementAt()可以從事件序列中取值指定index的事件,如果不存在,則無響應。 如果想要在獲取不到事件的時候發出響應使用elementAtOrError() |
2.5 其他操作符
名稱 | 功能介紹 |
---|---|
map | public final Observable map(Function mapper) 遍歷被觀察者發送的事件,可以對事件進行二次處理 |
flatMap | public static Observable fromIterable(Iterable source) 可以將事件序列中的元素進行整合加工,返回一個新的被觀察者,flatMap 並不能保證事件的順序 |
concatMap | public final Observable concatMap(Function> mapper) 功能與flatMap,但是concatMap可以保證事件的順序 |
buffer | public final Observable> buffer(int count, int skip) 從需要發送的事件中獲取一定數量的事件,並將這些事件放到緩衝區中一次性發出 |
groupBy | public final Observable> groupBy(Function keySelector) 將發送的數據進行分組,每個分組都會返回一個被觀察者 |
scan | public final Observable scan(BiFunction accumulator) 將時間以一定的邏輯聚合起來 |
reduce | public final Maybe reduce(BiFunction reducer) 操作符的作用也是將發送數據以一定邏輯聚合起來, 區別在於 scan() 每處理一次數據就會將事件發送給觀察者,而 reduce() 會將所有數據聚合在一起纔會發送事件給觀察者 |
window | public final Observable> window(long count) 將事件按照count指定的數量分組,一次性發送一組事件 |
concat/concatArray | public static Observable concat(ObservableSource source1, …, ObservableSource N4) public static Observable concatArray(ObservableSource… sources) 可以將多個觀察者組合在一起,然後按照之前發送順序發送事件。功能與concat相同,只是concatArray參數接收數組。 需要注意的是,concat() 最多只可以發送4個事件。如果其中有一個被觀察者發送了一個 onError 事件,那麼就會停止發送事件 |
merge/mergeArray | public static Observable merge(Iterable> sources) … 功能與concat相同,只是merge可以併發,不是按照被觀察者的順序發送事件 |
concatArrayDelayError mergeArrayDelayError |
public static Observable concatArrayDelayError(ObservableSource… sources) 如果事件發送過成中出現了onError事件,該方法可以延遲到所有被觀察者都發送完事件後再執行onError |
zip | public static Observable zip(Iterable> sources, Function zipper) 會將多個被觀察者合併,根據各個被觀察者發送事件的順序一個個結合起來,最終發送的事件數量會與源 Observable 中最少事件的數量一樣 |
collect | public final Single collect(Callable initialValueSupplier, BiConsumer collector) 將要發送的事件收集到定義的數據結構中 |
startWith/startWithArray | public final Observable startWith(T item) public final Observable startWithArray(T… items) 在發送事件之前追加事件,startWith() 追加一個事件,startWithArray() 可以追加多個事件。追加的事件會先發出 |
count | public final Single count() 返回被觀察者發送事件的數量 |
delay | public final Observable delay(long delay, TimeUnit unit) 延時發送事件 |
還有其他操作符,像onErrorResumeNext、retry、repeat、all、skipWhile等等等,這裏就不一一列舉了,如果需要,可以去自行查詢RxjavaDoc 。
3 總結
本章主要是介紹了RxJava2,比較了與RxJava的差異,還列舉了一堆讓人看着頭疼的操作符,都是些概念性的東西,最關鍵的是學會如何把RxJava應用到自己的項目中。流行的框架固然好,但是盲目的追風只會導致項目更加難以開發和維護,更不要談什麼效率了。適合你的纔是最好的。
下一章節,會具體介紹RxJava2的基本使用方法。