RxJava BackPressureStrategy.DROP将新任务排队,而不是删除它们

时间:2018-04-29 06:53:53

标签: android kotlin rx-java rx-java2

我的Android活动中的代码如下所示。在滚动事件上,它通过expensiveHttpCall() ThreadPoolExecutor调用SynchronousQueueDiscardPolicy&amp; class MyActivity : AppCompatActivity() { val recyclerView: RecyclerView . val oneAtATimeExecutor = ThreadPoolExecutor(1, 1, 1L, TimeUnit.SECONDS, SynchronousQueue<Runnable>(), ThreadPoolExecutor.DiscardPolicy() ) private val scrollListener: RecyclerView.OnScrollListener = object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) Log.e("rx","triggered!") oneAtATimeExecutor.execute { expensiveHttpCall() } } } override fun onCreate(savedInstanceState: Bundle?) { //... recyclerView.addOnScrollListener(scrollListener) //... } private fun expensiveHttpCall() { Thread.sleep(2000L) Log.e("rx", "done!") } } 导致在最后一次调用仍在运行时丢弃新的调用。

RxJava

我无法使用PublishProcessor的{​​{1}}实现相同的行为:

class MyActivity : AppCompatActivity() {

    val recyclerView: RecyclerView

    val processor = PublishProcessor.create<Unit>()

    private val scrollListener: RecyclerView.OnScrollListener = object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            Log.e("rx","triggered!")
            processor.onNext(Unit)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {

        //...

        recyclerView.addOnScrollListener(scrollListener)

        //...

        processor.onBackpressureDrop().observeOn(Schedulers.newThread())
                .subscribe { expensiveHttpCall() }
    }

    private fun expensiveHttpCall() {
        Thread.sleep(2000L)
        Log.e("rx", "done!")
    }
}

令我惊讶的是,在滚动后,控制台会打印出一堆"triggered"条消息。然后在2秒的继承率上打印"done!"的次数与"triggered"次打印的次数相同。这有效地表现得像队列而不是预期。 我做错了什么?

1 个答案:

答案 0 :(得分:1)

observeOn有一个内部队列,用于存储有限数量的项目。对于同步任务,您可以将队列大小限制为1:

processor.onBackpressureDrop()
   .observeOn(Schedulers.io(), false, 1)
   .subscribe { expensiveHttpCall() }

对于异步子任务,您可以使用有限并发的flatMap

processor.onBackpressureDrop()
   .flatMap({
       Flowable.just(1)
       .subscribeOn(Schedulers.io())
       .doOnNext { expensiveHttpCall() }
   }, 1)