RxJava onBackpressureBuffer不会发出项

时间:2016-10-20 08:55:25

标签: android rx-java rx-android ui-thread backpressure

我目睹了onBackpressureBuffer的奇怪行为,我不确定它是否是有效行为或错误。

我有一个以特定速率发出项目的tcp调用(使用流和输入流,但仅用于某些信息)

除此之外,我已经创建了一个使用create的observable,每次准备就会发出一个项目。

让我们称之为消息()。

然后我这样做:

messages()
   .subscribeOn(Schedulers.io())
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe({//do some work});

我注意到使用分析工具很少抛出MissingBackPressureException,因此我已将onBackpressureBuffer添加到呼叫中。

如果我在observeOn之后添加它:

messages()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .onBackpressureBuffer()
    .subscribe({//do some work})

每个工作都很好,但这意味着只有在它进入UI主线程后它才会缓冲,所以我更喜欢它是这样的:

messages()
    .onBackpressureBuffer()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({//do some work});

事情开始变得奇怪。

我注意到messages()会一直发出项目,但在某些时候它们会停止发送给订阅者。

更确切地说,在完成了16项之后,显而易见的是缓冲区将开始持有物品而不会将它们向前传递。

一旦我用某种超时机制取消messages(),它将导致messages()发出onError()并且缓冲区将立即发出它保存的所有项目(它们将是处理)。

我已经检查过是否订购了太多工作的用户错误,但事实并非如此,他已经完成了,但他仍然没有得到这些物品......

request(n)完成后,我还尝试在订阅者中使用onNext()方法询问一个项目,但缓冲区没有表现出来。

我怀疑Main Android UI Thread的消息传递系统带有背压导致这种情况,但我无法解释原因。

有人可以解释为什么会这样吗?这是一个错误还是一个有效的行为? TNX!

2 个答案:

答案 0 :(得分:5)

根据所描述的行为,不知道messages()如何,这与this question

类似的同一池死锁

您没有尝试的解决方法是将.onBackpressureBuffer 置于 subscribeOnobserveOn之间。

messages()
.subscribeOn(Schedulers.io())
.onBackpressureBuffer()           // <---------------------
.observeOn(AndroidSchedulers.mainThread())
.subscribe({//do some work});

答案 1 :(得分:1)

Question不同,但答案归结为同样的事情。 observeOn构造函数的实现:OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize)

public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
    this.scheduler = scheduler;
    this.delayError = delayError;
    this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;

}

最后一行指向缓冲区大小。

Android上的buffer size16

解决方案只是将更大的缓冲区大小传递给observeOn(Scheduler scheduler, int bufferSize)运算符:

messages()
    .observeOn(AndroidSchedulers.mainThread(), {buffer_size})

小心不要过高的价值,因为Android的内存有限。