#kotlin #kotlin-multiplatform
#kotlin #kotlin-мультиплатформенный
Вопрос:
Я работаю над мультиплатформенным проектом Kotlin. И я пытаюсь использовать таймер и таймер обратного отсчета, но я не могу получить доступ kotlin.concurrent.fixedRateTimer
к модулю или import kotlin.concurrent.timer
в commonMain
модуле.
Однако kotlin.concurrent
доступно:
Это root 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()
}
Ответ №1:
Как сказал Qaz, функция, которую вы пытаетесь использовать в обычном коде, предназначена только для JVM.
Обычно в KMP, когда у вас все еще нет общей функциональности, уже встроенной в фреймворк, вы можете использовать разные подходы:
- Используйте чужую библиотеку (например, moko-time) — лучшее место для поиска библиотек здесь.
- Используйте собственные классы framworks с помощью механизма
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
}
}
Ответ №2:
Функция, которую вы пытаетесь использовать, предназначена только для JVM. See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/fixed-rate-timer.html
Комментарии:
1. Как я могу добиться такой же функциональности там?