满足延迟执行、立即执行,每次任务间隔时长,总时长的任务
使用1
Kotlin
class TimeViewModel:Viewmodel(){
//测试延迟5秒开始执行任务,然后每隔1秒执行1次,总执行时间60秒
fun testTime(){
var startTime = System.currentTimeMillis()
log("执行 开始 startTime:${startTime}")
val job = viewModelScope.startTime(
interval = 5000,
duration = 1000,
totalTime = 60*1000,
onNext = {count->
log("执行次数:${count}")
},
onFinish = {
log("执行结束")
log("执行 结束 总耗时:${System.currentTimeMillis() - startTime}")
}
)
viewModelScope.launch {
delay(20000)
log("模拟执行手动结束")
job.cancel()
}
}
}
使用2
Kotlin
//立即执行任务,然后每隔1秒执行1次,总执行时间60秒
val job = viewModelScope.startTime(
duration = 1000,
totalTime = 60*1000,
onNext = {count->
log("执行次数:${count}")
},
onFinish = {
log("执行结束")
log("执行 结束 总耗时:${System.currentTimeMillis() - startTime}")
}
)
使用3
Kotlin
/*
立即执行任务,然后每间隔1秒执行1次,
要么手动调用 job.cancel(),要么等所在协程生命周期结束,才会结束,但不会回调 onFinish
*/
val job = viewModelScope.startTime(
duration = 1000,
onNext = {count->
log("执行次数:${count}")
},
onFinish = {
log("执行结束")
log("执行 结束 总耗时:${System.currentTimeMillis() - startTime}")
}
)
使用4
Kotlin
/*
延迟5秒再执行任务,然后每间隔1秒执行1次,
要么手动调用 job.cancel(),要么等所在协程生命周期结束,才会结束,但不会回调 onFinish
*/
val job = viewModelScope.startTime(
interval = 5000,
duration = 1000,
onNext = {count->
log("执行次数:${count}")
},
onFinish = {
log("执行结束")
log("执行 结束 总耗时:${System.currentTimeMillis() - startTime}")
}
)
//代码封装
Kotlin
/**
* @param interval 单位毫秒,用于定时器延迟时间开启,例如:interval = 5000,则是5秒后才会开始倒计时
* @param duration 单位毫秒,用户每次定时任务间隔时长执行1次,例如 duration = 1000,则每间隔1秒执行1次
* @param totalTime 单位毫秒,用于定时器执行的总时长,
* 如果为空的话,会一直在运行,直到手动调用cancel 方法,或者所在协程声明周期结束 而结束
* @onNext(count) ,返回每次执行的次数
* @onFinish() 任务正常执行完成
*/
fun CoroutineScope.startTime(
interval:Long? = 0,
duration:Long,
totalTime:Long? = null,
onNext:(Int)->Unit,
onFinish:(()->Unit)? = null
):Job{
if (duration<=0){
throw IllegalArgumentException("间隔时间必须大于0")
}
return this.launch {
interval?.let { _interval->
if (_interval>0){
delay(_interval)
}
}
var isStart = true
var runAllTotalTime:Long = 0
var count = 0
while (isStart){
if (totalTime!= null && totalTime>0 && runAllTotalTime>= totalTime){
isStart = false
onFinish?.invoke()
}else{
delay(duration)
runAllTotalTime+=duration
count+=1
onNext.invoke(count)
}
}
}
}