2014-12-11 46 views
0

我正在使用以下Observable执行常规任务。 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()和其他过滤器,但它以某种方式不会给我所需的效果,或者我不知道如何正确应用它们。

请注意,我不希望创建一个新的观察到的,每次迭代(我可以使用该邮政编码),因为我想确保代码不会从多个线程执行。

+1

我的解决方案将是:调用'subscribe'当设备醒来,并呼吁'unsubscribe'当睡觉。 – zsxwing 2014-12-11 09:03:21

回答

1

当你的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(); 
} 
+0

是的,我完全同意你的看法。在设备休眠时,不能使Rx跳过事件的正确方式。唯一的解决办法是停止Rx。所以这需要实施。 - 但除此之外,还有一个问题是迭代可能需要更长的时间[设想一下REST端点的调用,其中端点无法访问并需要一些时间来超时],在这种情况下,我想跳过事件。我们可以结合使用吗? – 2014-12-11 15:42:37

+1

我会在每次调用函数时保存当前时间,并将其与上一次运行时进行比较。如果它比750毫秒早,我会完全跳过身体。 – akarnokd 2015-03-10 21:23:44