无法在 Kotlin Multiplatform 中访问 fixedRateTimer
Cannot access fixedRateTimer in Kotlin Multiplatform
我正在从事 Kotlin Multiplatform 项目。我正在尝试使用计时器和倒计时计时器,但我无法访问 commonMain
模块中的 kotlin.concurrent.fixedRateTimer
或 import kotlin.concurrent.timer
。
但是 kotlin.concurrent
可用:
这是根 build.gradle
:
plugins {
kotlin("multiplatform")
id("com.android.library")
id("kotlin-android-extensions")
}
// ...
kotlin {
//...
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.10")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.10")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
//...
}
}
//...
}
}
我想知道是否可以在那里使用这些方法。如果没有,如何在commonMain
模块中写一个定时器和倒数定时器?
我曾尝试使用 Coroutines
实现相同的功能但失败了,因为它们不精确:
fun doAfter(delay: Long, action: () -> (Unit)) = launch {
delay(delay)
action.invoke()
}
fun countdown(time: Long, tick: Long, onTick: () -> (Unit), onFinish: () -> (Unit)) = launch {
val ticks = (time / tick).toInt()
repeat(ticks) {
onTick()
delay(tick)
}
onFinish()
}
您尝试使用的功能仅限于 JVM。看
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/fixed-rate-timer.html
正如 Qaz 所说,您尝试在公共代码中使用的函数是 JVM only。
通常在 KMP 中,当您仍然没有框架内置的通用功能时,您可以采用不同的方法:
- 使用其他库(例如 moko-time) - Best place for searching libraries is here。
- 通过
expect
/actual
机制 使用原生框架类
只是给你和可以做什么的例子(不确定这是否适合你或是否能满足你的需要。这只是为了让你朝着正确的方向前进,最重要的是我写的东西不能做好生产准备 [-;)
commonMain:Timer.kt
expect class KMMTimer(
name: String? = null,
interval: Long,
delay: Long,
action: () -> Unit
) {
val name: String?
val interval: Long
val delay: Long
fun start()
fun cancel()
fun isRunning(): Boolean
}
androidMain:Timer.kt
import java.util.*
import kotlin.concurrent.fixedRateTimer
actual class KMMTimer actual constructor(
actual val name: String?,
actual val interval: Long,
actual val delay: Long,
action: () -> Unit
) {
private var timer: Timer? = null
private val action = action
actual fun start() {
if (!isRunning()) {
timer = fixedRateTimer(
name = name,
initialDelay = delay,
period = interval
) {
action()
}
}
}
actual fun cancel() {
timer?.cancel()
timer = null
}
actual fun isRunning(): Boolean {
return timer != null
}
}
iosMain:Timer.kt
import platform.Foundation.NSDate
import platform.Foundation.NSRunLoop
import platform.Foundation.NSRunLoopCommonModes
import platform.Foundation.NSTimer
actual class KMMTimer actual constructor(
actual val name: String?,
actual val interval: Long,
actual val delay: Long,
action: () -> Unit
) {
private var timer: NSTimer? = null
private var action = action
actual fun start() {
if (!isRunning()) {
timer = NSTimer(
fireDate = NSDate(
NSDate().timeIntervalSinceReferenceDate + (delay.toDouble() / 1000)
),
interval = (interval.toDouble() / 1000),
repeats = true,
block = {
action()
}
)
timer?.let {
NSRunLoop.currentRunLoop().addTimer(it, NSRunLoopCommonModes)
}
}
}
actual fun cancel() {
timer?.invalidate()
timer = null
}
actual fun isRunning(): Boolean {
return timer != null
}
}
我正在从事 Kotlin Multiplatform 项目。我正在尝试使用计时器和倒计时计时器,但我无法访问 commonMain
模块中的 kotlin.concurrent.fixedRateTimer
或 import kotlin.concurrent.timer
。
但是 kotlin.concurrent
可用:
这是根 build.gradle
:
plugins {
kotlin("multiplatform")
id("com.android.library")
id("kotlin-android-extensions")
}
// ...
kotlin {
//...
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.10")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.10")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
//...
}
}
//...
}
}
我想知道是否可以在那里使用这些方法。如果没有,如何在commonMain
模块中写一个定时器和倒数定时器?
我曾尝试使用 Coroutines
实现相同的功能但失败了,因为它们不精确:
fun doAfter(delay: Long, action: () -> (Unit)) = launch {
delay(delay)
action.invoke()
}
fun countdown(time: Long, tick: Long, onTick: () -> (Unit), onFinish: () -> (Unit)) = launch {
val ticks = (time / tick).toInt()
repeat(ticks) {
onTick()
delay(tick)
}
onFinish()
}
您尝试使用的功能仅限于 JVM。看 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/fixed-rate-timer.html
正如 Qaz 所说,您尝试在公共代码中使用的函数是 JVM only。
通常在 KMP 中,当您仍然没有框架内置的通用功能时,您可以采用不同的方法:
- 使用其他库(例如 moko-time) - Best place for searching libraries is here。
- 通过
expect
/actual
机制 使用原生框架类
只是给你和可以做什么的例子(不确定这是否适合你或是否能满足你的需要。这只是为了让你朝着正确的方向前进,最重要的是我写的东西不能做好生产准备 [-;)
commonMain:Timer.kt
expect class KMMTimer(
name: String? = null,
interval: Long,
delay: Long,
action: () -> Unit
) {
val name: String?
val interval: Long
val delay: Long
fun start()
fun cancel()
fun isRunning(): Boolean
}
androidMain:Timer.kt
import java.util.*
import kotlin.concurrent.fixedRateTimer
actual class KMMTimer actual constructor(
actual val name: String?,
actual val interval: Long,
actual val delay: Long,
action: () -> Unit
) {
private var timer: Timer? = null
private val action = action
actual fun start() {
if (!isRunning()) {
timer = fixedRateTimer(
name = name,
initialDelay = delay,
period = interval
) {
action()
}
}
}
actual fun cancel() {
timer?.cancel()
timer = null
}
actual fun isRunning(): Boolean {
return timer != null
}
}
iosMain:Timer.kt
import platform.Foundation.NSDate
import platform.Foundation.NSRunLoop
import platform.Foundation.NSRunLoopCommonModes
import platform.Foundation.NSTimer
actual class KMMTimer actual constructor(
actual val name: String?,
actual val interval: Long,
actual val delay: Long,
action: () -> Unit
) {
private var timer: NSTimer? = null
private var action = action
actual fun start() {
if (!isRunning()) {
timer = NSTimer(
fireDate = NSDate(
NSDate().timeIntervalSinceReferenceDate + (delay.toDouble() / 1000)
),
interval = (interval.toDouble() / 1000),
repeats = true,
block = {
action()
}
)
timer?.let {
NSRunLoop.currentRunLoop().addTimer(it, NSRunLoopCommonModes)
}
}
}
actual fun cancel() {
timer?.invalidate()
timer = null
}
actual fun isRunning(): Boolean {
return timer != null
}
}