我想在onCreate
中创建一个新线程,并使用post
上的View
与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
。
我做错了什么?
答案 0 :(得分:5)
潜在的问题实际上与Kotlin无关。
问题是,如果视图当前附加到视图层次结构,View.post()
仅在主线程上成功调度其工作。视图的最终附加不会发生在setContentView()
时。它发生在一段时间后。
如果当前未附加post()
的主题视图(如问题中所示),View
会为当前主题创建RunQueue
(存储为本地线程)并安排RunQueue
上的工作。
因此,给定样本的问题如下。由于未在主线程上调用View.post()
,因此它将为当前的非主线程创建新的RunQueue
,而不检查它是否由{{1}定向(作为主线程)。这意味着预定的Looper
基本上会进入Runnable
,直到RunQueue
开始才会处理。在此处显示的情况下,Looper
永远不会启动,新线程终止,并且永远不会执行工作。
如果带有Looper
的新主题延迟到附加视图后,例如,当在其上注册了点击时,post
可能会安排主要工作线。但是这不是这里的情况,因为帖子发生1)在附加视图之前,2)在不同的非post
线程上立即终止。
答案 1 :(得分:0)
我能够通过从post
启动线程来解决这个问题,即
view.post({
thread() {
info("before post")
view.post({ info("inside post") })
info("after post")
}
})
但我想了解为什么我需要这样做。
答案 2 :(得分:0)
我建议你看看处理程序。它是一种在不同线程上执行操作时更新UI对象的更安全的方法。基本上你只需要将处理程序对象传递给你的线程以便更新Ui
此处有更多信息 http://developer.android.com/intl/pt-br/reference/android/os/Handler.html