Timer 暂停/恢复接收中的定时器/延迟

Timer 暂停/恢复接收中的定时器/延迟,timer,rx-java,reactive-programming,kotlin,Timer,Rx Java,Reactive Programming,Kotlin,我正在尝试使用rxjava暂停/恢复一个延迟的操作,但令人惊讶的是,我找不到有关如何执行该操作的任何详细信息 显然,我知道如何创建一个特定的计时器线程并跟踪时间,但我正在寻找一种更优雅、更具反应性的方法 我有三个不同的观察对象,playDetected,一个用于pauseDetected,另一个用于stopDetected。我想在PLAY的某个延迟后发射一些东西,但是当我的pause observable发射时暂停,当我得到另一个PLAY 到目前为止我拥有的:(它是用kotlin编写的,但是Ja

我正在尝试使用
rxjava
暂停/恢复一个延迟的操作,但令人惊讶的是,我找不到有关如何执行该操作的任何详细信息

显然,我知道如何创建一个特定的
计时器
线程并跟踪时间,但我正在寻找一种更优雅、更具反应性的方法

我有三个不同的观察对象,
playDetected
,一个用于
pauseDetected
,另一个用于
stopDetected
。我想在
PLAY
的某个延迟后发射一些东西,但是当我的pause observable发射时暂停,当我得到另一个
PLAY

到目前为止我拥有的:(它是用
kotlin
编写的,但是
Java
、伪代码或任何语言都可以作为答案)


我的延迟有效,当我检测到
停止
时,它成功地消除了延迟,以便下一个
播放
可以再次启动它。但是当检测到有东西发出时,如何暂停和恢复呢?

以下是我最终的做法:

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()
private val currentTimer=AtomicLong()
私人娱乐重置计时器(){
currentTimer.set(0)
}
私人娱乐轨道不同(有效载荷:StateWithTrack)=有效载荷.track!=trackPlaying.get()

不久前,我也在寻找RX“定时器”解决方案,但没有一个能满足我的期望。因此,您可以在这里找到我自己的解决方案:

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);
}
AtomicLong elapsedTime=new AtomicLong();
AtomicBoolean=新的AtomicBoolean();
AtomicBoolean stopped=新的AtomicBoolean();
公共可流动startTimer(){//创建并启动timper
恢复。设置(true);
停止。设置(false);
返回可流动。间隔(1,时间单位。秒)
.takeWhile(勾选->!已停止.get())
.filter(勾选->恢复.get())
.map(勾选->elapsedTime.addAndGet(1000));
}
public void pauseTimer(){
恢复。设置(false);
}
公共无效恢复计时器(){
恢复。设置(true);
}
公共无效停止计时器(){
停止。设置(true);
}
public void addToTimer(整数秒){
elapsedTime.addAndGet(秒*1000);
}

如果出现延迟,只需过载
interval
延迟功能。

我想恢复后,您希望在延迟停止时开始,而不是从开始?我的意思是,您的延迟为10秒,假设已经过了6秒,然后发生了pauseEvent。一旦playEvent将被发射,延迟现在应该是4秒(因为初始延迟是10秒,6秒过去了?是的,所以这就是为什么我认为延迟可能不适用于此。我需要以某种方式保持计时器的状态。我正在使用interval(1秒)开发另一个解决方案对于滴答声,这似乎有效。我会在更多的测试后在这里发布答案。这与你的问题相关吗?:谢谢@yurgis,事实上是这样,尽管它不完全相同
private val trackPlaying = AtomicReference<Track>()
private val currentTimer = AtomicLong()

private fun resetTimer() {
    currentTimer.set(0)
}

private fun trackIsDifferent(payload: StateWithTrack) = payload.track != trackPlaying.get()
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);
}