如何在 Android Studio ( kotlin ) 中创建计时器?
How to create timer in Android Studio ( kotlin )?
我想在 Android Studio 中使用 kotlin 创建一个程序,我在其中使用计时器,它每约 20 毫秒执行一次操作并无限运行。我使用了这样的东西:
object : CountDownTimer(10000,20){
override fun onTick(millisUntilFinished: Long) {
}
override fun onFinish() {
start()
}
}.start()
但问题是,一段时间后,计时器开始变慢,应该过去 1 秒,但实际上是 6 秒。将动作更改为 40 毫秒或更多只会帮助一小会儿,因为稍后它仍然会变慢。我看到人们使用的计时器实际上是这样工作的,没有任何问题,但它在 Java 中,当我试图在 Android Studio 的帮助下将其更改为 Kotlin 时(我从未使用过 Java),它最终无法正常工作(启动后,应用程序每次都崩溃)。有人知道如何创建或使用除我在上面显示的 Kotlin 中的 CountDownTimer 之外的其他计时器吗?
编辑:
我忘了添加适合我的代码。它基本上是我接受的答案,但我必须进行一些更改才能使其工作,所以这里是:
val timerName = lifecycleScope.launch(Dispatchers.IO) {
while (isActive) {
lifecycleScope.launch {
doSomething()
}
delay(20L)
}
}
这很可能是因为 onTick()
和 onFinish()
中的函数是在与计数器工作的同一个协程中调用的,所以您可能需要 launch
另一个协程来不阻塞计时器范围
另外这个 CountDownTimer
API 目前是实验性的,所以我想不推荐使用它,也许你可以这样做:
val timerJob = scope.launch(Dispatcher.IO) {
while (isActive) {
scope.launch { doSomething() }
delay(20L)
}
}
我没有测试它,但它应该具有完全相同的行为(但不会阻塞计时器),它将 运行 直到 scope
自行取消(f.e。生命周期范围)或者您将通过调用 timerJob.cancel()
手动取消它
isActive
布尔值负责检查协程是否仍处于活动状态(因此循环不会“泄漏”)
不幸的是,如果你 运行 在这个 doSomething()
调用中有一些繁重的东西会超过这 20 毫秒的延迟,那么会发生一些并发问题,所以它应该很简单
如果您的“游戏”太重以至于这 20 毫秒的延迟太小,那么很可能使用协程不是实现您的想法的最佳方法
我想在 Android Studio 中使用 kotlin 创建一个程序,我在其中使用计时器,它每约 20 毫秒执行一次操作并无限运行。我使用了这样的东西:
object : CountDownTimer(10000,20){
override fun onTick(millisUntilFinished: Long) {
}
override fun onFinish() {
start()
}
}.start()
但问题是,一段时间后,计时器开始变慢,应该过去 1 秒,但实际上是 6 秒。将动作更改为 40 毫秒或更多只会帮助一小会儿,因为稍后它仍然会变慢。我看到人们使用的计时器实际上是这样工作的,没有任何问题,但它在 Java 中,当我试图在 Android Studio 的帮助下将其更改为 Kotlin 时(我从未使用过 Java),它最终无法正常工作(启动后,应用程序每次都崩溃)。有人知道如何创建或使用除我在上面显示的 Kotlin 中的 CountDownTimer 之外的其他计时器吗?
编辑: 我忘了添加适合我的代码。它基本上是我接受的答案,但我必须进行一些更改才能使其工作,所以这里是:
val timerName = lifecycleScope.launch(Dispatchers.IO) {
while (isActive) {
lifecycleScope.launch {
doSomething()
}
delay(20L)
}
}
这很可能是因为 onTick()
和 onFinish()
中的函数是在与计数器工作的同一个协程中调用的,所以您可能需要 launch
另一个协程来不阻塞计时器范围
另外这个 CountDownTimer
API 目前是实验性的,所以我想不推荐使用它,也许你可以这样做:
val timerJob = scope.launch(Dispatcher.IO) {
while (isActive) {
scope.launch { doSomething() }
delay(20L)
}
}
我没有测试它,但它应该具有完全相同的行为(但不会阻塞计时器),它将 运行 直到 scope
自行取消(f.e。生命周期范围)或者您将通过调用 timerJob.cancel()
isActive
布尔值负责检查协程是否仍处于活动状态(因此循环不会“泄漏”)
不幸的是,如果你 运行 在这个 doSomething()
调用中有一些繁重的东西会超过这 20 毫秒的延迟,那么会发生一些并发问题,所以它应该很简单
如果您的“游戏”太重以至于这 20 毫秒的延迟太小,那么很可能使用协程不是实现您的想法的最佳方法