用携程 Coroutine 写一个定时器

1,045 阅读1分钟

定时器

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"

import kotlinx.coroutines.*

// 定义一个函数,启动一个定时器协程
fun startTimer(scope: CoroutineScope, delayTimeMillis: Long, action: () -> Unit) {
    scope.launch {
        delay(delayTimeMillis)  // 延迟指定的时间(毫秒)
        action()                // 延迟后执行的操作
    }
}

// 使用
class MyActivity : AppCompatActivity() {
    
    private val job = Job()
    private val coroutineScope = CoroutineScope(Dispatchers.Main + job)
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 启动定时器,例如每隔5秒执行一次操作
        startTimer(coroutineScope, 5000L) {
            // 这里是定时器触发后要执行的代码块
            Log.d("Timer", "Timer tick at ${System.currentTimeMillis()}")
            
            // 如果你想让定时器重复执行,可以在这里再次调用startTimer
            // 注意避免可能出现的内存泄漏或不必要的任务累积
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        job.cancel() // 当Activity销毁时取消所有协程
    }
}

请注意,上面的示例创建了一个单次的定时器。如果你希望有一个周期性触发的定时器,你可以将延迟和动作的执行放在一个循环中:

// 使用周期性定时器的方式与上述类似
fun startPeriodicTimer(scope: CoroutineScope, intervalMillis: Long, action: () -> Unit) {
    scope.launch {
        while (isActive) {  // 检查协程是否还活跃
            delay(intervalMillis)  // 等待指定的时间间隔
            action()               // 执行传入的代码块
        }
    }
}

此代码应该在主线程上创建一个协程(CoroutineScope(Dispatchers.Main)),因此任何更新UI的操作都是安全的。如果你的定时器动作不涉及UI,可以选择在 IODefault dispatcher上运行。

记得在合适的生命周期事件(如 onDestroy)中取消相关的协程,以避免内存泄漏或不必要的资源占用。