如何防止Observable排队Timer迭代

时间:2014-12-11 05:44:24

标签: rx-java rx-android

我正在使用以下Observable来执行常规任务。当类首次加载到内存中时启动Observable,然后定期执行我的代码。因为它是一个单一的Observable,所以保证[从我的测试看起来的假设]代码永远不会再次启动并且并行处理,以防它运行的时间长于间隔。

private static Subscription subscription = Observable.timer(0, 1000, TimeUnit.MILLISECONDS)
        .flatMap(new Func1<Long, Observable<String>>() {
            @Override public Observable<String> call(Long aLong) {

                // some code

                return Observable.just(null);
            }
        }).subscribeOn(Schedulers.newThread()).observeOn(Schedulers.newThread())
        .subscribe();

但是这也有一个缺点,即rxjava累积延迟发射并在延迟迭代完成后以快速序列启动它们。示例:如果定时器被编程为每1000毫秒迭代并且迭代n需要5000毫秒,则迭代n + 1,n + 2,n + 3等顺序启动,但是一个接一个地启动,并且不遵守定时器间隔

并不是那么糟糕,但真正的问题是Android睡了几个小时后会发生什么。因为一旦设备唤醒,rxjava会以快速序列启动所有错过的迭代,这会给性能带来很大影响。

如何告诉rxjava忘记错过的迭代?如果迭代需要更长的时间,我或者想要在迭代完成时启动计时器,或者我想丢弃错过的迭代并在到期时开始下一次迭代。我尝试使用sample()和其他过滤器,但它不知何故给我预期的效果,或者我不知道如何正确应用它们。

请注意,我不想为每次迭代创建一个新的Observable(我可以使用zip),因为我想确保代码不是从多个线程执行的。

1 个答案:

答案 0 :(得分:2)

当您的Android设备处于睡眠模式时,请勿要求Rx跳过某些事件。但是停止Rx!

当您订阅流时,您有一个处理程序可以取消订阅此流。

Subscription subscription = Observable.timer(1, SECONDS).subscribe();

在您的活动的OnPause()方法中,您可以通过在订阅上调用unsubscribe()方法停止该流。

@Override
public void onPause() {
    subscription.unsubscribe();
}

在您的活动的onResume()方法中,您可以在您的信息流中再次订阅

@Override
public void onResume() {
   subscription = Observable.timer(1, SECONDS).subscribe();
}