cash長什麼樣:
rx.exceptions.MissingBackpressureException
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.onNext(OperatorObserveOn.java:130)
at rx.internal.operators.OperatorSubscribeOn$1$1$1.onNext(OperatorSubscribeOn.java:76)
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54)
at rx.internal.operators.OperatorTake$1.onNext(OperatorTake.java:73)
at rx.internal.operators.OnSubscribeTimerPeriodically$1.call(OnSubscribeTimerPeriodically.java:52)
at rx.Scheduler$Worker$1.call(Scheduler.java:120)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:784)
異常原因:拋出MissingBackpressureException往往就是因爲,被觀察者發送事件的速度太快,而觀察者處理太慢,而且你還沒有做相應措施,所以報異常。
場景重現:
//被觀察者在主線程中,每1ms發送一個事件
Observable.interval(1, TimeUnit.MILLISECONDS)
//.subscribeOn(Schedulers.newThread())
//將觀察者的工作放在新線程環境中
.observeOn(Schedulers.newThread())
//觀察者處理每1000ms才處理一個事件
.subscribe(new Action1() {
@Override
public void call(Long aLong) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.w("TAG","---->"+aLong);
}
});
解決方案:
1)過濾(拋棄) :加onBackpressureDrop操作符即可,Observable產生的事件可能都是我們需要的,一般來說不會拋棄
代碼示例
Observable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressureDrop()
.observeOn(Schedulers.newThread())
.subscribe(new Subscriber() {
@Override
public void onStart() {
Log.w("TAG","start");
// request(1);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.e("ERROR",e.toString());
}
@Override
public void onNext(Long aLong) {
Log.w("TAG","---->"+aLong);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
2)緩存:加操作符 onBackpressurebuffer 即可, 就是雖然被觀察者發送事件速度很快,觀察者處理不過來,但是可以選擇先緩存一部分,然後慢慢讀。 ==》相關類似的操作符:buffer,window...
代碼示例同上,換操作符即可
Observable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressurebuffer()
.observeOn(Schedulers.newThread())
.subscribe(new Subscriber() {
}
.......