首页 > 解决方案 > 多线程 runOnUiThread

问题描述

我需要从线程更新 UI。为此,我创建了一条 Toast 消息来测试该功能是否按预期工作。在我的线程中,我运行函数“runOnUiThread”并在该函数中放置一条 Toast 消息,如下所示......

runOnUiThread {
    Toast.makeText(this, "DIALOG Start", Toast.LENGTH_SHORT).show()
}

虽然这确实有效,但它也不起作用。Toast 消息保留在设备屏幕上。我已经在模拟器和现场设备上对其进行了测试。每次我运行代码时,Toast 消息都会停留在屏幕上。

但是,如果我将 toast 消息分离为扩展类型函数,它会按预期工作。

val toast = Toast.makeText(this@MainActivity, "Dialog finish", Toast.LENGTH_SHORT)

runOnUiThread {
    toast.show()
}

这按预期工作。

我想知道,为什么?两组代码都调用 runOnUiThread()。两者都在调用 Toast 消息。两者有什么区别?

这是使用 Kotlin 并更新 UI 和从线程更新的产品吗?这是因为线程没有停止吗?如果我打电话,吐司会消失吗

thread.stop() Although it is deprecated.

这是有效的代码:

progressDoalog!!.max = 100
val toast = Toast.makeText(this@MainActivity, "Dialog finish", Toast.LENGTH_SHORT)
Thread {
   try {
        while (progressDoalog!!.progress <= progressDoalog!!.max) {
        Thread.sleep(50)
        handle.sendMessage(handle.obtainMessage())
        if (progressDoalog!!.progress == progressDoalog!!.max) {
        progressDoalog!!.dismiss()
        runOnUiThread {
           toast.show()
        }
    }
  }
 } catch (e: Exception) {
       e.printStackTrace()
 }
}.start()

标签: androidmultithreadingkotlinandroid-runonuithread

解决方案


如果您修复缩进,问题的原因会更清楚:

val toast = Toast.makeText(this@MainActivity, "Dialog finish", Toast.LENGTH_SHORT)
Thread {
    try {
        while (progressDoalog!!.progress <= progressDoalog!!.max) {
            Thread.sleep(50)
            handle.sendMessage(handle.obtainMessage())
            if (progressDoalog!!.progress == progressDoalog!!.max) {
                progressDoalog!!.dismiss()
                runOnUiThread {
                    toast.show()
                }
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}.start()

这个while循环永远运行。一旦progress等于max,您就开始一遍又一遍地显示吐司。您的while循环条件将永远为真,因此它永远不会停止调用show()您的 Toast。

在您的非工作代码中,您在循环的每次迭代中都创建了一个新的 Toast,因此一旦一个 toast 消失,后面就会有另一个相同的 Toast。

在您的“工作”代码中,您show()一遍又一遍地调用同一个 Toast 实例,因此它只出现一次。但是,您将泄漏一个不朽的线程。


推荐阅读