【问题标题】:Cannot access fixedRateTimer in Kotlin Multiplatform无法在 Kotlin Multiplatform 中访问 fixedRateTimer
【发布时间】:2020-10-21 06:54:21
【问题描述】:

我正在开发一个 Kotlin 多平台项目。我正在尝试使用计时器和倒数计时器,但我无法访问 commonMain 模块中的 kotlin.concurrent.fixedRateTimerimport 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()
    }

【问题讨论】:

    标签: kotlin kotlin-multiplatform


    【解决方案1】:

    正如 Qaz 所说,您尝试在公共代码中使用的函数是 JVM only

    通常在 KMP 中,当您还没有框架内置的通用功能时,您可以采用不同的方法:

    1. 使用其他人的库(例如 moko-time)- 搜索库的最佳位置是 here
    2. 通过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】:

      【讨论】:

      • 我怎样才能在那里实现相同的功能?
      猜你喜欢
      • 1970-01-01
      • 2019-12-31
      • 2019-07-13
      • 2020-10-24
      • 2021-07-07
      • 2021-03-19
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      相关资源
      最近更新 更多