接着上篇文章講,一般情況下,上篇文章講的就夠我們用的了。一般我們工作的環境也不會出現背壓問題。但是爲了既然Rxjava設計了背壓策略,我又在整理資料,那就還是整理一下吧。
什麼是背壓問題呢?接上上篇水管的舉例說,就是上游水管的水流速度大於下游水管的水流速度。上游的水管流的快,下游 的水管流的慢,來不及流出去的水就堆積在水管中,水管積水多了,就爆了,就要OOM了。
//關注點1
Observable<String> observable=Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d("TAG","subscribe");
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onComplete();
}
});
如代碼所示,subscribe 方法中可以多次調用emitter.onNext()方法,這個方法調用一次就發送一個事件,如果調用的很多,而觀察者處理不過來,那麼這些事件就會堆積在緩存中,如果一直累計不處理,內存就不夠用,出現OOM了。
Rxjava用了Flowable來處理這種問題。Flowable的用法和Observable類似,這裏直接上代碼。
Flowable<Object> objectFlowable = Flowable.create(new FlowableOnSubscribe<Object>() {
@Override
public void subscribe(FlowableEmitter<Object> emitter) throws Exception {
emitter.onNext("數據 --->1");
emitter.onNext("數據 --->2");
emitter.onNext("數據 --->3");
emitter.onNext("數據 --->4");
emitter.onComplete();
}
}, BackpressureStrategy.DROP);//背壓策略
被觀察者Flowable和Observable不一樣的就是Flowable.create()方法裏面多了一個參數,這個參數主要是指定緩存裏多的事件怎麼處理,下面還會仔細將。
還有一點不同就是觀察者的不同了,如代碼所示:
objectFlowable.subscribe(new Subscriber<Object>() {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(2);//每次只拉去兩個世間
}
@Override
public void onNext(Object value) {
Log.i("ceshi", "onNext value = " + value);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
Log.i("ceshi", "onComplete ");
}
});
如代碼所示,onSubscribe()方法的參數發生了變化,變成了subscription,subscription.request(int n);方法指定每次觀察者能處理的事件的個數爲n。如果被觀察者發送的事件大於2,那麼觀察者只處理前2個事件,剩餘的多的事件放在緩存中。
鏈式調用
Flowable.create(new FlowableOnSubscribe<Object>() {
@Override
public void subscribe(FlowableEmitter<Object> emitter) throws Exception {
emitter.onNext("數據 --->1");
emitter.onNext("數據 --->2");
emitter.onNext("數據 --->3");
emitter.onNext("數據 --->4");
emitter.onComplete();
}
}, BackpressureStrategy.DROP)//背壓策略
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Object>() {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(2);
}
@Override
public void onNext(Object value) {
Log.i("ceshi", "onNext value = " + value);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
Log.i("ceshi", "onComplete ");
}
});
調用的結果如下:
11-29 11:46:52.311 31656-31656/com.airbridge.rxjavademo I/ceshi: onNext value = 數據 --->1
11-29 11:46:52.311 31656-31656/com.airbridge.rxjavademo I/ceshi: onNext value = 數據 --->2
如上面代碼所示,被觀察者Flowable中,subscribe方法裏emitter.onNext()調用了四次,但是因爲觀察者指定的能處理的事件個數是2,即subscription.request(2)。所以 觀察者回調函數onNext()只執行了前兩次,剩餘的事件放在緩存中。
至於被觀察者發送了那麼多事件,都累計在緩存中怎麼處理呢,這就要看 Flowable.create()的第二個參數了,也就是背壓策略。
RxJava支持的背壓的方式:
- BackpressureStrategy.BUFFER
- BackpressureStrategy.DROP
- BackpressureStrategy.LATEST
BUFFER 就是不丟棄請求,把收到所有請求都緩存起來,當來請求處理時再發出去。
DROP 和 LATEST 都是丟棄請求,服務端通過請求產生配額,將配額告訴客戶端,客戶端收到多少配額就發送多少請求。配額消耗完之後,客戶端丟棄之後的請求。
DROP即配額消耗完之後直接丟棄請求。而LATEST則緩存最後(最新)的一條請求,當服務端又發來新的配額時,將緩存的最新的請求發送給服務端。
上一篇講的是無背壓的基礎使用:Rxjava的使用_1
如果需要上面的源碼,可以去下載 RxjavaDemo.zip
文章裏面有些東西是從別處COPY過來的,都是概念性的東西,不想打字就直接拷貝了。