0

次の Observable を使用して通常のタスクを実行しています。Observable は、クラスが最初にメモリにロードされたときに起動され、定期的にコードを実行します。これは単一の Observable であるため、コードが 2 回目に起動されることはなく、間隔よりも長く実行された場合に並列で処理されることが [私のテストから見えるように] 保証されます。

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 を使用できます)。

4

1 に答える 1

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();
}
于 2014-12-11T13:12:23.640 に答える