【问题标题】:Storing ScheduledFuture in Class Variable in Kotlin在 Kotlin 的类变量中存储 ScheduledFuture
【发布时间】:2023-04-11 06:36:01
【问题描述】:

我目前正在尝试使用 ScheduledExecutorService 在 Kotlin 中启动计划任务,然后在类中存储对其 ScheduledFuture 的引用,以便稍后我可以在需要时使用其他函数取消该任务。

companion object {

        val submitPool = Executors.newScheduledThreadPool(1)
        var taskHandle : ??? // What type do I make this?

        val newTask= object : Runnable {
            override fun run() {
                foo()
            }
        }
      
        fun onStatusChange(connected : Boolean) {
            if(connected) {
                    taskHandle = submitPool.scheduleWithFixedDelay(newTask, msUpdateRate, msUpdateRate, TimeUnit.MILLISECONDS)
                }
            } else { 
                taskHandle.cancel(true) // Cancel the task
            }
        }
}

我知道scheduleWithFixedDelay 函数返回ScheduledTask<?>,但在Kotlin 变量中,Android Studio 说它是ScheduledTask<*> 类型,我无法存储。如何将该结果作为变量存储在伴随对象上,以便稍后调用cancel()

到目前为止,我尝试的任何操作都会引发类型不匹配的语法错误。我应该将结果转换为ScheduledTask<Unit> 吗?我对 Java 和 Kotlin 都非常陌生,尤其是 Star Projection <*> 的工作原理以及它与此的关系。

【问题讨论】:

    标签: java android kotlin


    【解决方案1】:

    可以使用ScheduledTask<*> 作为类型。 * 表示编译器不知道类型,但编译器不需要知道类型就可以调用cancel()

    您确实需要使该属性可以为空,因为它并不总是存在。然后你可以在取消时将它设置回null。

    newTask 可能应该是私有的,并且您可以使用更短的 lambda 语法来创建 Runnables,如下所示。

    companion object {
    
      val submitPool = Executors.newScheduledThreadPool(1)
      var taskHandle: ScheduledTask<*>? = null
      private val newTask = Runnable {
          foo()
        }
          
      fun onStatusChange(connected: Boolean) {
        if(connected) {
          taskHandle = submitPool.scheduleWithFixedDelay(newTask, msUpdateRate, msUpdateRate, TimeUnit.MILLISECONDS)
        } else { 
          taskHandle?.cancel(true) // Cancel the task (if it exists)
          taskHandle = null
        }
      }
    }
    

    或者,您可以传递 Callable 而不是 Runnable,以便知道类型。如果 foo 返回 Unit(即不返回任何值),则使用 &lt;Unit&gt; 作为类型。

    companion object {
    
      val submitPool = Executors.newScheduledThreadPool(1)
      var taskHandle: ScheduledTask<Unit>? = null
      private val newTask = Callable {
          foo()
        }
          
      fun onStatusChange(connected: Boolean) {
        if(connected) {
          taskHandle = submitPool.scheduleWithFixedDelay(newTask, msUpdateRate, msUpdateRate, TimeUnit.MILLISECONDS)
        } else { 
          taskHandle?.cancel(true) // Cancel the task (if it exists)
          taskHandle = null
        }
      }
    }
    

    【讨论】:

    • 感谢您非常详尽的回答!
    猜你喜欢
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2012-07-15
    • 1970-01-01
    相关资源
    最近更新 更多