Ami*_*mir 4 kotlin kotlin-multiplatform
我正在开发一个 Kotlin 多平台项目。我正在尝试使用计时器和倒计时器,但我无法访问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")
//...
}
}
//...
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以在那里使用这些方法。如果没有,我如何在模块中编写计时器和倒计时器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()
}
Run Code Online (Sandbox Code Playgroud)
正如 Qaz 所说,您尝试在通用代码中使用的功能仅限于 JVM。
通常在 KMP 中,当您仍然没有框架内置的通用功能时,您可以采用不同的方法:
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
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1107 次 |
最近记录: |