Kotlin中如何将ScheduledFuture存储为类变量以取消定时任务
问题解答
正确的变量声明方式
直接声明为可空的ScheduledFuture<*>即可,初始值设为null:
var taskHandle : ScheduledFuture<*>? = null
相关说明
- 首先纠正一个认知误差:
scheduleWithFixedDelay的返回值类型是ScheduledFuture<?>,不是ScheduledTask<?>,你看到的IDE提示可能是缩写或者笔误。 - 你不需要强制转换为
ScheduledFuture<Unit>,完全没有必要,还会带来不必要的类型转换警告。
关于星号投影<*>的作用
Kotlin中的星号投影对应Java的无界通配符?,在你的场景下,你存储taskHandle的唯一目的是调用cancel()方法取消任务,完全不需要读取任务的返回结果,所以你根本不需要关心这个泛型参数的具体类型,用<*>就是最合理的写法,cancel()方法的调用完全不受泛型参数影响。
修正后的完整代码
import java.util.concurrent.Executors import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit companion object { val submitPool = Executors.newScheduledThreadPool(1) // 正确的类型声明,可空,初始为null var taskHandle : ScheduledFuture<*>? = null private const val msUpdateRate = 1000L // 这里替换为你自己的间隔时间 val newTask= object : Runnable { override fun run() { foo() } } fun onStatusChange(connected : Boolean) { if(connected) { // 每次启动新任务前先取消之前的旧任务,避免重复启动 taskHandle?.cancel(true) taskHandle = submitPool.scheduleWithFixedDelay(newTask, msUpdateRate, msUpdateRate, TimeUnit.MILLISECONDS) } else { // 加安全调用避免空指针 taskHandle?.cancel(true) } } private fun foo() { // 你的任务逻辑 } }
额外注意事项
- 启动新任务前建议先取消已经存在的旧任务,避免多次触发
onStatusChange(true)导致重复启动多个定时任务。 - 如果你的类生命周期结束后不需要再用这个线程池,建议调用
submitPool.shutdown()回收资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者BordinPls
相关产品推荐
相关产品推荐

