android 使用协程CoroutineScope 实现定时器

满足延迟执行、立即执行,每次任务间隔时长,总时长的任务

使用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)
                }
            }
        }
    }
相关推荐
四维碎片17 分钟前
【Qt】配置安卓开发环境
android·开发语言·qt
百***992424 分钟前
MySql的慢查询(慢日志)
android·mysql·adb
安卓兼职framework应用工程师25 分钟前
android 15.0 Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标
android·拖拽·workspace·长按拖拽
雨白1 小时前
Jetpack Compose Navigation3:返回栈管理、大屏适配与自定义策略
android
CIb0la4 小时前
安卓16系统升级后(Google pixel 8/8pro 9/9pro xl 10/10pro xl)救砖及Root方法
android·运维·生活
Ya-Jun5 小时前
项目实战Now in Android:项目模块说明
android·架构·kotlin
@Aurora.6 小时前
【MySQL】基础
android
ooooooctober6 小时前
PHP代码审计框架性思维的建立
android·开发语言·php
q***82917 小时前
图文详述:MySQL的下载、安装、配置、使用
android·mysql·adb
沐怡旸7 小时前
【底层机制】Ashmem匿名共享内存:原理与应用深度解析
android·面试