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);
}