handler.postDelayed 在 runnable 中显示 Kotlin 中的语法错误 - Android

handler.postDelayed from within runnable shows syntax error in Kotlin - Android

private val progressTask = Runnable {
    runOnUiThread { if (!tvMessage.text.isEmpty()) tvMessage.text = "" }
    pbLoading.progress++
    when {
        pbLoading.progress == 600 -> finalFunction()
        pbLoading.progress % 20 == 0 -> runOnUiThread {
            tvMessage.text = messages[pbLoading.progress / 20]
        }
    }
    handler.postDelayed(this, 1000)
}

此代码在 this 关键字下给我一个语法错误。说这个错误指向我的 activity 而不是 runnable 本身。我该如何解决这个问题?

你不能用普通的 lambda 来做到这一点。为了使 this 引用 Runnable,请使用 object 语法:

val runnable = object : Runnable {
    override fun run() {
        println("$this runs in a runnable")
    }
}

它稍微冗长一点,这就是你付出的代价。

This code is giving me an syntax error under the this keyword

首先,在 Kotlin

中修改您的 runOnUiThread 方法
private val progressTask = Runnable {
        activity!!.runOnUiThread(Runnable {
            Handler().postDelayed(Runnable {

                // YOUR CODE

            }, 1000)
        })
    }

您在 kotlin 处理程序中使用了如下代码

 private val progressTask = Runnable {
        runOnUiThread { if (!tvMessage.text.isEmpty()) tvMessage.text = "" }
        pbLoading.progress++
        when {
            pbLoading.progress == 600 -> finalFunction()
            pbLoading.progress % 20 == 0 -> runOnUiThread {
                tvMessage.text = messages[pbLoading.progress / 20]
            }
        }
        Handler().postDelayed(this, 1000)
    }

如果传递这个关键字然后 运行() 方法实现。

  override fun run() {
}

使用以下代码:

//创建处理器实例

private val handler = Handler()

private val progressTask = object : Runnable {
    override fun run() {
        println("$this runs in a runnable")

        runOnUiThread { if (!tvMessage.text.isEmpty()) tvMessage.text = "" }
        pbLoading.progress++
        when {
            pbLoading.progress == 600 -> finalFunction()
            pbLoading.progress % 20 == 0 -> runOnUiThread {
                tvMessage.text = messages[pbLoading.progress / 20]
            }
        }
        handler.postDelayed(this, 1000)
    }
}

让我为您提供更深入的问题解决方案:帮自己一个忙,改用 Kotlin 协程。这就是您的代码与它们搭配使用时的样子:

fun showLoadingProgress(tvMessage: TextView, pbLoading: ProgressBar) = launch(UI) {
    if (!tvMessage.text.isEmpty()) tvMessage.text = ""
    with(pbLoading) {
        do {
            delay(1000)
            if (progress++ % 20 == 0) tvMessage.text = messages[progress / 20]
        } while (progress < 600)
        finalFunction()
    }
}

如果您担心他们仍然是 "experimental",那只是意味着他们的 API 还没有最终确定。 JetBrains 已经 保持与实验性 API 的向后兼容性,我可以亲自证明其实施的稳健性——我从未遇到过任何问题。


您提到您担心您还必须暂停进度监视器,然后稍后再恢复。使用协同程序,您可以按如下方式实现它:

  1. showLoadingProgress() 内你会写

    suspendCoroutine { cont -> this.progressMonitorContinuation = cont }
    

    这意味着存在 var progressMonitorContinuation: Continuation<Unit>?.

  2. 当您准备好恢复进度监视器时,写

    val cont = this.progressMonitorContinuation!!
    this.progressMonitorContinuation = null
    launch(UI) { cont.resume(Unit) }