我正在研究Kotlin Multiplatform项目。而且我正在尝试使用计时器和倒数计时器,但无法访问kotlin.concurrent.fixedRateTimer
模块中的import kotlin.concurrent.timer
或commonMain
。
这是根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()
}
答案 0 :(得分:3)
您要使用的功能仅是JVM。看到 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/fixed-rate-timer.html
答案 1 :(得分:3)
正如Qaz所说,您尝试在通用代码中使用的函数是JVM only。
通常在KMP中,当您仍然没有框架内置的通用功能时,可以采用不同的方法:
expect
/actual
机制使用本地framworks类仅举例说明可以做些什么(不确定是否适合您或满足您的需求。这只是为了使您处于正确的方向,而我写的所有内容都不能用于生产。完全准备就绪[-;)
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
}
}