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)
                }
            }
        }
    }
相关推荐
_阿南_2 小时前
Android文件读写和分享总结
android
通玄11 小时前
Jetpack Compose 入门系列(六):Navigation 3 页面导航
android
rocpp13 小时前
Android 多语言切换实战:从 Context 到 Android 13 应用语言适配
android·kotlin
释然小师弟14 小时前
Android开发十年:反思与回顾
android·后端·嵌入式
黄林晴16 小时前
用了这么久 Koin Scope,原来一直都用错了?
android·kotlin
爱勇宝1 天前
我做了一个只用来搜歌词的小 App
android·前端·后端
众少成多积小致巨1 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
Coffeeee2 天前
如何使用Glide和Coil加载WebP动图
android·kotlin·glide
Kapaseker2 天前
5 分钟搞懂 Kotlin DSL
android·kotlin
恋猫de小郭2 天前
AI Agent 开发究竟是啥?如何用 AI 开发 Agent ?深入浅出给你一套概念
android·前端·ai编程