我正在开发具有后台数据同步功能的
Android应用程序.
我正在使用RxJava定期在服务器上发布一些数据.
除此之外,我想向用户提供一个按钮“强制同步”,这将立即触发同步.
我知道如何使用Observable.interval()来定期推送数据,我会知道如何使用Observalbe.just()来推送那个被强制的数据,但是如果发生这种情况,我想排队一个在前一个仍然运行时被触发.
我正在使用RxJava定期在服务器上发布一些数据.
除此之外,我想向用户提供一个按钮“强制同步”,这将立即触发同步.
我知道如何使用Observable.interval()来定期推送数据,我会知道如何使用Observalbe.just()来推送那个被强制的数据,但是如果发生这种情况,我想排队一个在前一个仍然运行时被触发.
所以让我们举个例子,当1分钟是自动同步的时间间隔,让我们说同步持续40秒(我过分夸张,只是为了更容易点).现在如果有任何机会,当自动仍然运行时,用户按下“强制”按钮(反之亦然 – 强制人员仍在运行时自动触发),我想排队第二个同步请求,就像第一个完成.
我画了这个图片,这可能会给你一些更多的看法:
如你所见,自动触发(由一些Observable.interval()),并且在同步的中间,用户按“强制”按钮.现在我们要等待第一个请求完成,然后重新开始强制请求.
有一点,当强制请求正在运行时,新的自动请求被再次触发,只是将其添加到队列中.在最后一个从队列中完成后,一切都停止,然后自动再次安排在稍后.
希望有人可以指出我正确的运算符如何做到这一点.我已经尝试过Observable.combineLatest(),但是队列列表是在开始时分派的,当我添加新的同步到队列时,在上一个操作完成时它不会继续.
任何帮助是极大的赞赏,
达科
解决方法
您可以通过将定时器与按钮点击Observable / Subject合并来实现,使用onBackpressureBuffer的排队效果,并将其中的处理结合到一起,以确保每次运行一个.
PublishSubject<Long> subject = PublishSubject.create(); Observable<Long> periodic = Observable.interval(1,1,TimeUnit.SECONDS); periodic.mergeWith(subject) .onBackpressureBuffer() .concatMap(new Func1<Long,Observable<Integer>>() { @Override public Observable<Integer> call(Long v) { // simulates the task to run return Observable.just(1) .delay(300,TimeUnit.MILLISECONDS); } } ).subscribe(System.out::println,Throwable::printStackTrace); Thread.sleep(1100); // user clicks a button subject.onNext(-1L); Thread.sleep(800);