我尝试使用rx-Java
暂停/恢复延迟操作,令人惊讶的是,我无法找到有关如何执行此操作的详细信息。
显然,我知道如何通过创建一个特定的Timer
线程并跟踪时间来做到这一点,但我正在寻找一种更优雅和更具反应性的方式。
我有三个不同的可观察对象playDetected
,一个用于pauseDetected
,一个用于stopDetected
。我想在PLAY
的某个延迟后发出一些东西,但是当我的暂停可观察发出时暂停,并在我得到另一个PLAY
时恢复
到目前为止我所拥有的内容:(它是用kotlin
编写的,但是Java
,伪代码或任何语言都可以用来回答)
val playSubscription = playDetected
.delay(DELAY, SECONDS, schedulers.computation)
.subscribe { emitFinalEvent(it) }
stopDetected.subscribe { playSubscription.unsubscribe() }
我的延迟有效,当我检测到STOP
时,它会成功删除延迟,以便下一个PLAY
可以再次启动它。但是当pauseDetected
发出一些东西时如何暂停和恢复?
答案 0 :(得分:1)
以下是我最终如何做到这一点:
playDetected
.doOnNext {
if (trackIsDifferent(it)) resetTimer()
trackPlaying.set(it.track)
}
.switchMap { state ->
interval(1, SECONDS, schedulers.computation)
.doOnNext { currentTimer.incrementAndGet() }
.takeUntil(merge(pauseDetected, stopDetected.doOnNext { resetTimer() }))
.filter { currentTimer.get() == DELAY }
.map { state }
}.subscribe { emitFinalEvent(it)) }
使用:
private val trackPlaying = AtomicReference<Track>()
private val currentTimer = AtomicLong()
private fun resetTimer() {
currentTimer.set(0)
}
private fun trackIsDifferent(payload: StateWithTrack) = payload.track != trackPlaying.get()
答案 1 :(得分:0)
前段时间,我也在寻找RX&#34;计时器&#34;解决方案,但没有满足我的期望。所以你可以找到我自己的解决方案:
AtomicLong elapsedTime = new AtomicLong();
AtomicBoolean resumed = new AtomicBoolean();
AtomicBoolean stopped = new AtomicBoolean();
public Flowable<Long> startTimer() { //Create and starts timper
resumed.set(true);
stopped.set(false);
return Flowable.interval(1, TimeUnit.SECONDS)
.takeWhile(tick -> !stopped.get())
.filter(tick -> resumed.get())
.map(tick -> elapsedTime.addAndGet(1000));
}
public void pauseTimer() {
resumed.set(false);
}
public void resumeTimer() {
resumed.set(true);
}
public void stopTimer() {
stopped.set(true);
}
public void addToTimer(int seconds) {
elapsedTime.addAndGet(seconds * 1000);
}
如果出现延迟,只需延迟interval
函数重载。