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)
                }
            }
        }
    }
相关推荐
Lei活在当下8 小时前
【项目踩坑实录】并发环境下,Glide缓存引起的图片加载异常
android·debug·glide
my_power52010 小时前
检出git项目到android studio该如何配置
android·git·android studio
三少爷的鞋13 小时前
Repository 方法设计:suspend 与 Flow 的决选择指南(以朋友圈为例)
android
阿里云云原生14 小时前
Android App 崩溃排查指南:阿里云 RUM 如何让你快速从告警到定位根因?
android·java
cmdch201716 小时前
手持机安卓新增推送按钮功能
android
攻城狮201516 小时前
【rk3528/rk3518 android14 kernel-6.10 emcp sdk】
android
何妨呀~16 小时前
mysql 8服务器实验
android·mysql·adb
QuantumLeap丶17 小时前
《Flutter全栈开发实战指南:从零到高级》- 25 -性能优化
android·flutter·ios
木易 士心18 小时前
MVC、MVP 与 MVVM:Android 架构演进之路
android·架构·mvc
百锦再18 小时前
国产数据库的平替亮点——关系型数据库架构适配
android·java·前端·数据库·sql·算法·数据库架构