我封装了一段等待8个小时才结束。我需要重复里面的任务,直到时间达到8小时。如何在开始下一个周期之前等待任务结束,而不是固定的延迟时间?
fun startPeriodicTask(timeout: Long, block: suspend CoroutineScope.() -> Unit) {
periodicTask = viewModelScope.launcher {
while (dataService.timeConfigData.runTime.value!!.toLong() < dataService.timeConfigData.timeEnd.value!!.toLong()) {
withTimeout(timeout) {
// 执行任务
XLog.v("startPeriodicTask run block")
block()
}
delay(timeout)
}
}
}
vm.startPeriodicTask(2000) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mVibrator?.vibrate(VibrationEffect.createOneShot(1000, 255))
} else {
mVibrator?.vibrate(longArrayOf(1000, 2000), 1)
}
}
我的理解是,这是不可行的,因为协程是一个递归过程,所以当我挂起它的时候,我就等不及了,主线程就被阻塞了。
====================================================== ===============
我是按照broot的方法修改的。其实我并没有等,只是启动了协程任务,导致while在短时间内被重复了无数次。不知道我的修改是否正确。
fun startPeriodicTask(timeout: Long, block:() -> Unit) {
// periodicTask = viewModelScope.launcher {
while (dataService.timeConfigData.runTime.value!!.toLong() <
dataService.timeConfigData.timeEnd.value!!.toLong()) {
XLog.v("startPeriodicTask run block")
block()
// delay(timeout)
// }
}
}
vm.dataService.
testConfigData.isSpeakerSwitch.observe(viewLifecycleOwner) {
if (it) {
vm.startPeriodicTask(25000) {
play {
XLog.d("play end")
}
}
}
}
fun play(onCompleted: () -> Unit) {
stop()
mMediaPlayer = MediaPlayer.create(requireContext(), R.raw.testsignal)
mMediaPlayer?.setOnCompletionListener(OnCompletionListener {
stop()
onCompleted()
})
mMediaPlayer?.start()
}
我又解决了这个问题。我用协程在块中等待来解决。感谢@broot
fun startPeriodicTask(timeout: Long, block:suspend CoroutineScope.() -> Unit) {
periodicTask = viewModelScope.launcher {
while (dataService.timeConfigData.runTime.value!!.toLong() < dataService.timeConfigData.timeEnd.value!!.toLong()) {
// 执行任务
XLog.v("startPeriodicTask run block")
block()
}
}
}
vm.dataService.testConfigData.isSpeakerSwitch.observe(viewLifecycleOwner) {
if (it) {
vm.startPeriodicTask(25000) {
play {
XLog.d("play end")
}
}
}
}
suspend fun play(onCompleted: () -> Unit): Boolean {
return suspendCancellableCoroutine { suspend ->
stop()
mMediaPlayer = MediaPlayer.create(requireContext(), R.raw.testsignal)
mMediaPlayer?.setOnCompletionListener(OnCompletionListener {
stop()
onCompleted()
suspend.resume(true) {
XLog.d("play end")
}
})
mMediaPlayer?.start()
}
}