【问题标题】:Posting to UI thread发布到 UI 线程
【发布时间】:2016-07-21 06:35:51
【问题描述】:

我想在onCreate 中创建一个新线程,并在View 上使用post 与UI 线程通信。但是,posted 语句似乎从未运行过。这是一个小例子:

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

我做错了什么?

【问题讨论】:

  • mb info() 实现中的某些内容?

标签: android multithreading kotlin android-handler ui-thread


【解决方案1】:

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

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

如果当前未附加post() 的主题视图(如问题中所示的情况),View 为当前线程创建一个RunQueue(存储为本地线程)并安排 RunQueue 的工作。

因此,给定样本的问题如下。由于View.post() 没有在主线程上调用,它将为当前的非主线程创建一个新的RunQueue,而不检查它是否由Looper 引导(与主线程一样)。这意味着计划的Runnable 本质上进入了RunQueue,直到Looper 开始才被处理。在此处显示的情况下,Looper 从未启动,新线程终止,工作从未执行。

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

【讨论】:

  • 在不依赖用户交互(如您的示例中的点击)的情况下,启动thread() 的正确时间是什么时候?
  • 我猜在 View 的 onAttachedToWindow() 或注册的 View.OnAttachStateChangeListener 期间。
  • 哦,顺便说一句,我从没想过它会是 Kotlin 特有的,而是将其标记为 Kotlin,以便查看最小复制示例的人可以弄清楚那是什么语言。
【解决方案2】:

我可以通过从post 启动线程本身来解决这个问题,即

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

但我想了解我为什么需要这样做。

【讨论】:

    【解决方案3】:

    我建议你看看 Handlers。在不同线程上执行操作时,它是更新 UI 对象的一种更安全的方法。基本上,您只需将处理程序对象传递给您的线程即可更新 Ui

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

    【讨论】:

      猜你喜欢
      • 2015-10-27
      • 2012-08-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-19
      • 2023-01-10
      • 2017-05-28
      相关资源
      最近更新 更多