概述
RxJava是響應式編程(Reactive Extensions)在JVM平臺上的實現,即用java語言實現的一套基于觀察者模式的異步編程接口,目前有1.x版本和2.x版本兩套實現。RxJave2即RxJave庫的2.x版本,這篇文章即介紹這個版本。
背景介紹
RxJava的1.x版本和2.x版本是不兼容的兩個庫,托管在不同分支上也使用不同的包名,官方指出1.x版本在2017年6月1日開始停止添加新內容,保持修改bug的狀態,并在2018年3月31日停止開發。
RxJava的2.0.1版本于2016年11月12日正式發布,和1.x版本并行開發。RxJave2按照Reactive-Streams標準對接口進行了重寫,繼續支持java 6+和Android 2.3+,性能得到提升,更方便使用java8的lambda表達式,并把1.x中的背壓功能單獨分離出來。
在功能使用方面,2.x和1.x是大同小異的,大部分操作符都沒變,實現原理也是相同的,所以下面會偏重介紹兩個版本的不同點,關于RxJave的一些共性的基礎的介紹可以參考本系列文章1.x版本部分。
簡單使用
2.x版本的包名已經改變,maven庫的gradle引用為:
compile 'io.reactivex.rxjava2:rxjava:x.y.z'
在1.x版本,被觀察者的角色主要使用Observable,在2.x版本中增加了Flowable和Maybe,Flowable是2.x版本負責背壓處理的被觀察者,Observable中不再支持背壓功能。
Flowable的簡單使用代碼如下:
Flowable flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
e.noNext(1);
e.onNext(2);
e.onNext(3);
e.onComplete();
}
}, FlowableEmitter.BackpressureMode.BUFFER);
Disposable disposable = flowable
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("RX", integer.toString());
}
})
.subscribe(new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);//設置請求數,不設置默認也是這個數
}
@Override
public void onNext(Integer integer) {
Log.d("RX", integer.toString());
}
@Override
public void onError(Throwable t) {
Log.d("RX", t.toString());
}
@Override
public void onComplete() {
Log.d("RX", "Complete");
}
});
我們可以看到create函數多了個參數,代表背壓策略,背壓策略后續會有文章詳細講解;subscribe函數的參數從Subscriber變成了FlowableEmitter;1.x版本的Action不見了,我們用的是Consumer;Subscriber其實也是用的Reactive-Streams規范中的Subscriber,比1.x多了onSubscribe函數,這個函數傳入的參數Subscription是很重要的,必須調用它的request方法,下層才能收到事件通知,當然,為了使用方便,這個方法在框架中是有默認調用的,設置默認請求數為Long.MAX_VALUE。從1.x到2.x細節變化還是不少的,但總體來看,使用起來跟1.x還是差不多,用過1.x的應該可以很快適應。
Reactive-Streams簡介
上面說到,2.x版本是根據Reactive-Streams實現的,所以再簡單介紹下Reactive-Streams。
Reactive Streams是一個基于JVM的面向流的庫包的標準和規范,具體如下:
1.處理潛在的無邊界限制的元素
2.順序
3.在組件之間異步傳遞元素
4.使用強制性的非堵塞的抗壓。
Reactive Streams由以下部分組成:
SPI:定義了不同實現組件之間的交互層和互操作性
API:定義 Reactive Streams用戶使用的類型
技術兼容Kit(TCK):實現的標準測試。
Reactive Streams是一個規范,構建系統的開發者們需要使用該規范的實現。Reactive Streams的目標是增加抽象層,而不是進行底層的流處理,規范將這些問題留給了庫實現來解決。
具體使用Reactive Streams比較簡單,只需實現幾個接口即可,就像上面說的,Reactive Streams的目標是增加抽象層,而不是進行底層的流處理,每個具體流處理庫可能都有自己的實現方式,但是只要大家都遵循了這個規范,那就可以無縫切換了。
Reactive Streams規范的一個主要目標是通過異步邊界來解耦系統組件。在同步世界中,每個功能或是操作都是按照順序處理的,一個接著一個;除了第一個外,其他每一個操作都依賴于前一個操作。這種方式增加了維護成本,并且不利于構建出響應式系統。
Reactive Streams規范的另一個主要目標是為壓力處理定義一種模型。流處理的理想范式是將數據從發布者推送到訂閱者,這樣發布者就可以快速發布數據,同時通過壓力處理來確保速度更快的發布者不會對速度較慢的訂閱者造成過載。壓力處理通過使用流控制來確保操作的穩定性并能實現優雅降級,從而提供彈性能力。
通過上面介紹,大家對Reactive Streams可能有了大概了解,這些大多是參考自一些權威寫的文章,內容偏向整體的抽象概述,具體可以參考Reactive Streams的接口代碼和實現規范的詳情,這些都在GitHub中給出了。
2.x與1.x差異概述
一些差異前面已經有所提及,這里再總結一下:
- maven地址和項目包名不同
- RxJave2不再接受參數為null的數據流,這么做會馬上拋出NullPointerException
- Observable和Flowable分別處理無背壓和有背壓功能部分
- 新增Maybe類型,可以看作Single和Completable的合體類
- 完全遵循Reactive Streams接口規范
- 方法都可以拋出異常
- Action系列接口被Consumer取代
- Func系列接口被重命名為Function系列
- 調用Subscription的request方法時就會調用noNext等周期函數,所以要把一些后面需要用到的初始化操作放在request函數調用之前。
- 少量操作符差異
更詳細內容可以參考官網
參考文章:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0907/6604.html
http://www.infoq.com/cn/news/2015/12/reactive-streams-introduction