发布到UI线程

我想在onCreate创建一个新线程,并使用View上的post与UI线程进行通信。 但是,编辑报表似乎并没有运行。 这是一个小例子:

 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 postafter post ,但从来没有inside post

我究竟做错了什么?

根本问题实际上与Kotlin无关。

问题是View.post()只在视图当前附加到视图层次结构的情况下,才在主线程上成功调度它的工作。 该视图的最后附加不会在setContentView() 。 事情发生一段时间后。

即使post()的主题视图当前未附加(如问题中所示), View为当前线程创建一个RunQueue (作为本地线程存储),并计划该RunQueue上的工作。

所以,给定样本的问题如下。 由于View.post()没有在主线程上调用,因此它将为当前的非主线程创建一个新的RunQueue ,而不检查它是否被Looper指令(如同主线程)。 这意味着预定的Runnable基本上进入一个RunQueue ,直到一个Looper启动才会被处理。 在这里显示的情况下, Looper从不启动,并且新线程终止,工作从不执行。

如果带有post的新线程被延迟到视图被附加之后,例如,当在其上注册点击时,该post可能能够在主线程上安排工作。 但是这不是这种情况,因为这个帖子出现在1)视图附加之前,2)在一个不同的非Looper线程立即终止。

我能够通过从post开始线程本身来解决这个问题,即

 view.post({ thread() { info("before post") view.post({ info("inside post") }) info("after post") } }) 

但我想明白为什么我需要这样做。

我会建议你看看处理程序。 在不同线程上执行操作时更新UI对象的更安全的方法。 基本上,你只需要传递处理程序对象到你的线程,以更新用户界面

更多信息在这里http://developer.android.com/intl/pt-br/reference/android/os/Handler.html