Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 即使在调用onBackpressureBlock()之后,也会丢失BackPressureException_Android_Reactive Programming_Rx Java - Fatal编程技术网

Android 即使在调用onBackpressureBlock()之后,也会丢失BackPressureException

Android 即使在调用onBackpressureBlock()之后,也会丢失BackPressureException,android,reactive-programming,rx-java,Android,Reactive Programming,Rx Java,我试图周期性地(每150ms)发出事件,即使上游可观测对象会更快地发送事件 但是我得到了missingbackpressureeexception,即使我调用了onBackpressureBlock() 代码: PS:Log.fatalError(err)只是我对Android.util.Log.e(…) 编辑 经过多次尝试和错误,这对我来说是一个无法解决的问题zipWith(Observable.interval…似乎是罪魁祸首,可能是框架缺陷。删除这些行(以及我的周期性发射功能)我的代码可以

我试图周期性地(每150ms)发出事件,即使上游可观测对象会更快地发送事件

但是我得到了
missingbackpressureeexception
,即使我调用了
onBackpressureBlock()

代码:

PS:
Log.fatalError(err)
只是我对
Android.util.Log.e(…)

编辑

经过多次尝试和错误,这对我来说是一个
无法解决的问题<代码>zipWith(Observable.interval…
似乎是罪魁祸首,可能是框架缺陷。删除这些行(以及我的周期性发射功能)我的代码可以正常工作。 我使用的主题可能从不同的线程调用了
onNext
,然后我对其执行Obeservable运算符。

我认为(但我不确定)问题在于您的背压配置在
zip
运算符之后

zip
操作员需要缓冲一个
observatable
的项目,以将其与另一个
observatable
进行压缩。这就是应该引发异常的缓冲区。(见附件)

为了解决您的问题,我认为您应该尝试在
zip
操作符中使用的一个(或每个)
Observable
上添加背压配置

例如:

obs.zipWith(Observable.interval(150, TimeUnit.MILLISECONDS).onBackPressureDrop());

obs.onBackPressureBlock().zipWith(Observable.interval(150, TimeUnit.MILLISECONDS));

以上来自@dwursteisen和@zsxwing的答案是正确的

间隔操作符是基于时间发出的操作符,因此是“热”的,不支持背压。因此,它将继续发出并填充zip的内部有界缓冲区,这将导致MissingBackpressureException

在处理“热”源(例如基于时间或用户事件的源)时,必须选择如何处理溢出的策略

在这种情况下,您需要将该策略置于
interval
操作符上

下面的代码显示了正在发生的事情以及处理这些事情的选项:

import java.util.concurrent.TimeUnit;

import rx.Observable;


public class ZipInterval {

    public static void main(String... args) {
        Observable<Long> slowHotSource = Observable.interval(1, TimeUnit.SECONDS);

        /** This one is fast and hot so will cause a MissingBackpressureException.
         *  
         * This is because a "hot" source based on time does not obey backpressure
         * and keeps emitting regardless of what the downstream asks for.
         * 
         * Examples of "hot" and "cold" and approaches to both can be found at:
         * https://speakerdeck.com/benjchristensen/reactive-programming-with-rx-at-qconsf-2014?slide=90 and
         * https://github.com/ReactiveX/RxJava/wiki/Backpressure
         * */ 
        // Observable<Long> fastHotSource = Observable.interval(1, TimeUnit.MILLISECONDS);

        /**
         * The following version of 'fastHotSource' composes a simple flow control strategy.
         */
        Observable<Long> fastHotSource = Observable.interval(1, TimeUnit.MILLISECONDS).onBackpressureDrop();

        Observable<String> zipped = Observable.zip(slowHotSource, fastHotSource, (s, f) -> {
            return s + " " + f;
        });

        // subscribe to the output
        System.out.println("---- zip output");
        zipped.take(10).toBlocking().forEach(System.out::println);

        /**
         * The outcome of the above is probably not what is expected though. 
         * 
         * This is because zip will buffer the output and then `fastHotSource` will drop until
         * the zip buffer asks for more.
         * 
         * For temporal or "hot" sources like this, using `withLatestFrom` or `combineLatest`
         * is often more appropriate than `zip`.
         */

        Observable<String> latest = slowHotSource.withLatestFrom(fastHotSource, (s, f) -> {
            return s + " " + f;
        });

        // subscribe to the output
        System.out.println("---- latest output");
        latest.take(10).toBlocking().forEach(System.out::println);
    }
}

尝试使用
combinelatetest
,因为combinelastest不会等待新值调用onNext,当新值到达函数时,它会使用最新值

您是否同时尝试了这两种方法?根据你的描述,很难知道哪一个太快了。
obs.zipWith(Observable.interval(150, TimeUnit.MILLISECONDS).onBackPressureDrop());

obs.onBackPressureBlock().zipWith(Observable.interval(150, TimeUnit.MILLISECONDS));
import java.util.concurrent.TimeUnit;

import rx.Observable;


public class ZipInterval {

    public static void main(String... args) {
        Observable<Long> slowHotSource = Observable.interval(1, TimeUnit.SECONDS);

        /** This one is fast and hot so will cause a MissingBackpressureException.
         *  
         * This is because a "hot" source based on time does not obey backpressure
         * and keeps emitting regardless of what the downstream asks for.
         * 
         * Examples of "hot" and "cold" and approaches to both can be found at:
         * https://speakerdeck.com/benjchristensen/reactive-programming-with-rx-at-qconsf-2014?slide=90 and
         * https://github.com/ReactiveX/RxJava/wiki/Backpressure
         * */ 
        // Observable<Long> fastHotSource = Observable.interval(1, TimeUnit.MILLISECONDS);

        /**
         * The following version of 'fastHotSource' composes a simple flow control strategy.
         */
        Observable<Long> fastHotSource = Observable.interval(1, TimeUnit.MILLISECONDS).onBackpressureDrop();

        Observable<String> zipped = Observable.zip(slowHotSource, fastHotSource, (s, f) -> {
            return s + " " + f;
        });

        // subscribe to the output
        System.out.println("---- zip output");
        zipped.take(10).toBlocking().forEach(System.out::println);

        /**
         * The outcome of the above is probably not what is expected though. 
         * 
         * This is because zip will buffer the output and then `fastHotSource` will drop until
         * the zip buffer asks for more.
         * 
         * For temporal or "hot" sources like this, using `withLatestFrom` or `combineLatest`
         * is often more appropriate than `zip`.
         */

        Observable<String> latest = slowHotSource.withLatestFrom(fastHotSource, (s, f) -> {
            return s + " " + f;
        });

        // subscribe to the output
        System.out.println("---- latest output");
        latest.take(10).toBlocking().forEach(System.out::println);
    }
}
---- zip output
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
---- latest output
0 1002
1 2002
2 3000
3 4001
4 5003
5 6001
6 7000
7 8002
8 9005
9 10000