在Android中使用RxJava窗口或缓冲区进行批处理吗?

时间:2018-06-26 16:51:33

标签: android rx-java rx-java2

我希望在api帖子之前实现批处理机制,以进行一些简单的事件收集和日志记录。 由于这是Android设备,因此我也想处理该服务是否停止的生命周期事件,因此,如果该服务已停止但尚未达到计数或时间,那么手动刷新缓冲窗口的方法是什么。

例如,我有一个PublishSubject(主题),创建一个flowable并对其执行窗口操作,如下所示:

subject.toFlowable(BackpressureStrategy.BUFFER)
            .window(30,
                    TimeUnit.SECONDS,
                    20,
                    true)
            .flatMapSingle { it.toList() }
            .subscribe (this::send)

如果我的服务/应用被暂停或终止,我只想发送缓冲区中的内容。

1 个答案:

答案 0 :(得分:0)

您面临的问题是在必要时停止观察并刷新窗口中的当前项目。 Flowable.window()运算符的文档说:

  

当源发布者完成或遇到错误时,结果发布者将发出当前窗口并传播来自源发布者的通知。

因此,您需要使Subject发出错误或完成。在大多数情况下,这不是与主题打交道的正确方法。让我们将Subject替换为易于完成的内容:

private val stopObserver = BehaviorSubject.create<Unit>() // (1)

private fun emitStop() { // (2)
    stopObserver.onNext(Unit)
}

private fun sourceSubject(): Flowable<Long> { // (3)
    return Flowable.interval(1, TimeUnit.SECONDS)
        .takeUntil(stopObserver.toFlowable(BackpressureStrategy.BUFFER)) // (4)
}

private fun runObservation() { // (5)
    sourceSubject()
        .window(10)
        .flatMapSingle { it.toList() }
        .doOnNext { Log.d("onNext", "${it.count()} items") }
        .subscribe()
}

重要部分的说明:

  1. 创建新的Subject,它在您意识到应用停止或暂停时发出。
  2. 您可以在需要时使用函数onNextSubject发出emitStop()事件
  3. sourceSubject()函数模仿您的来源Subject。这个每秒发射一次物品。
  4. takeUntil()运算符在传递的PublisherstopObserver)发出项时完成流。这样可以确保我们的总体source PublishersourceSubject)完成。
  5. 我使用的是window()运算符的简单版本,但是对于源发布者,它们都使用相同的原理。

可能的输出:

2019-11-30 10:48:54.527 D/onNext: 10 items
2019-11-30 10:49:04.524 D/onNext: 10 items
2019-11-30 10:49:14.525 D/onNext: 10 items
2019-11-30 10:49:19.056 D/onNext: 4 items