我的Android活动中的代码如下所示。在滚动事件上,它通过expensiveHttpCall()
ThreadPoolExecutor
调用SynchronousQueue
和DiscardPolicy
& 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"
次打印的次数相同。这有效地表现得像队列而不是预期。
我做错了什么?
答案 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)