发布到 UI 个话题
Posting to UI thread
我想在 onCreate
中创建一个新线程并使用 View
上的 post
与 UI 线程通信。但是,post
ed 语句似乎从来都不是 运行。这是一个小例子:
import android.app.Activity
import android.os.Bundle
import android.widget.TextView
import kotlin.concurrent.*
import org.jetbrains.anko.*
class MainActivity: Activity(), AnkoLogger {
protected override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val view = TextView(this)
setContentView(view)
thread() {
info("before post")
view.post({ info("inside post") })
info("after post")
}
}
}
查看日志,我只能看到before post
和after post
,但看不到inside post
。
我做错了什么?
我能够通过从 post
启动线程本身来解决这个问题,即
view.post({
thread() {
info("before post")
view.post({ info("inside post") })
info("after post")
}
})
但我想了解为什么我需要这样做。
我建议您看看 Handlers。在不同的线程上执行操作时,它是一种更安全的更新 UI 对象的方法。基本上你只需要将处理程序对象传递给你的线程以更新 Ui
这里有更多信息
http://developer.android.com/intl/pt-br/reference/android/os/Handler.html
根本问题实际上与 Kotlin 无关。
问题在于,如果视图 当前 附加到视图层次结构,则 View.post()
仅在主线程上成功安排其工作。视图的最终附加不会在 setContentView()
时发生。它发生在一段时间后。
如果 post()
的主题视图当前未附加(如问题中所示的情况),View
会为当前创建一个 RunQueue
thread(存储为本地线程)并安排 RunQueue
.
上的工作
因此,给定样本的问题如下。由于 View.post()
没有在主线程上调用,它将为当前的非主线程创建一个新的 RunQueue
,而不检查它是否被 Looper
引导(就像主线程)。这意味着计划的 Runnable
实质上进入 RunQueue
,直到 Looper
开始才处理。在此处显示的情况下,Looper
从未启动,新线程终止,并且工作从未执行。
如果带有 post
的新线程被延迟到附加视图之后,例如,当在其上注册点击时,post
可能会安排工作主线程。但这里的情况并非如此,因为 post 发生在 1) 附加视图之前,以及 2) 在立即终止的不同非 Looper
线程上。
我想在 onCreate
中创建一个新线程并使用 View
上的 post
与 UI 线程通信。但是,post
ed 语句似乎从来都不是 运行。这是一个小例子:
import android.app.Activity
import android.os.Bundle
import android.widget.TextView
import kotlin.concurrent.*
import org.jetbrains.anko.*
class MainActivity: Activity(), AnkoLogger {
protected override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val view = TextView(this)
setContentView(view)
thread() {
info("before post")
view.post({ info("inside post") })
info("after post")
}
}
}
查看日志,我只能看到before post
和after post
,但看不到inside post
。
我做错了什么?
我能够通过从 post
启动线程本身来解决这个问题,即
view.post({
thread() {
info("before post")
view.post({ info("inside post") })
info("after post")
}
})
但我想了解为什么我需要这样做。
我建议您看看 Handlers。在不同的线程上执行操作时,它是一种更安全的更新 UI 对象的方法。基本上你只需要将处理程序对象传递给你的线程以更新 Ui
这里有更多信息 http://developer.android.com/intl/pt-br/reference/android/os/Handler.html
根本问题实际上与 Kotlin 无关。
问题在于,如果视图 当前 附加到视图层次结构,则 View.post()
仅在主线程上成功安排其工作。视图的最终附加不会在 setContentView()
时发生。它发生在一段时间后。
如果 post()
的主题视图当前未附加(如问题中所示的情况),View
会为当前创建一个 RunQueue
thread(存储为本地线程)并安排 RunQueue
.
因此,给定样本的问题如下。由于 View.post()
没有在主线程上调用,它将为当前的非主线程创建一个新的 RunQueue
,而不检查它是否被 Looper
引导(就像主线程)。这意味着计划的 Runnable
实质上进入 RunQueue
,直到 Looper
开始才处理。在此处显示的情况下,Looper
从未启动,新线程终止,并且工作从未执行。
如果带有 post
的新线程被延迟到附加视图之后,例如,当在其上注册点击时,post
可能会安排工作主线程。但这里的情况并非如此,因为 post 发生在 1) 附加视图之前,以及 2) 在立即终止的不同非 Looper
线程上。