You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 02:06:03