android - 如何在 Kotlin 中使用 Thread.sleep()

标签 android kotlin android-layout sleep

这来自在此处找到的代码实验室的末尾附近:
Intro to debugging - Debugging example: accessing a value that doesn't exist
这都在 MainActivity.kt 文件中
这是我的 onCreate

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val helloTextView: TextView = findViewById(R.id.division_textview)
    helloTextView.text = "Hello, debugging!"

    division()
}
//...
这是 Google 提供的除法功能,但有 2 处更改我稍后会解释...
fun division() {
  val numerator = 60
  var denominator = 4
    repeat(4) {
     Thread.sleep(3000)
     findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}")
     Log.v(TAG, "${numerator / denominator}")
     denominator--
    }
  }
这些说明看起来像是他们期望的 sleep()接受秒,但 AS 表明它需要毫秒,所以我将它们的 3 更改为 3000。我添加了 Log.v(TAG, "${numerator / denominator}")看看发生了什么,因为它没有按预期进行。
这样做的目的是让模拟器创建一个正在更新的商的 gif。这在调试时应该很有帮助。
repeat() 之前,屏幕上什么都没有显示,甚至没有应用程序的名称。完成。
正如预期的那样,日志以 3 秒的间隔发生。
为什么布局在等待,如何让它在循环的每次迭代中更新?

最佳答案

老实说,根据他们提供的代码,我不知道 Codelab 在做什么。在 onCreate 之前,应用程序不会呈现任何内容(不是布局,也不是​​对布局的任何更改)完成,和 onCreate在运行所有代码之前不会完成,包括 repeat阻止 division它调用的函数。division没有启动任何工作线程,所以所有 Thread.sleep正在阻塞主线程 - 它正在挂起应用程序。你是对的,sleep确实需要一个毫秒值,而不是秒 - 我觉得他们实际上并没有运行这段代码,它充满了其他错误和不一致,老实说很难弄清楚你打算做什么。更改Log.d称呼? onCreate 中的那些? (它们实际上是指 Log.v 中的 division 调用,我假设)

以下是您在 Kotlin 中使用线程的方式——您需要创建一个新线程(这样您就离开了主线程,因此它实际上可以完成创建 Activity 并运行 UI):

fun division() {
    // create a new thread (and start it immediately)
    thread(start=true) {
        repeat(4) { i ->
            Thread.sleep(3000L)
            // assuming you've done the ``findViewById`` and assigned it to a variable
            runOnUiThread { divisionTextView.text = "$i" }
        }
    }
}
为简洁起见,这只是使用当前的重复编号( i )进行更新,但重要的是:
  • 您正在创建一个新线程来完成工作(并且正在 sleep )
  • 您正在使用 runOnUiThread (这是 Activity 上的一种方法)在主/UI线程上进行文本更新(同样的事情)。如果您尝试从另一个线程触摸 UI 它会崩溃

  • 您可以这样做的另一种方法是post通过 View 运行到 UI 线程,不妨使用 TextView :
    divisionTextView.post { divisionTextView.text = "$i" }
    
    协程在这里是一个更好的主意(你可以在主线程上运行它们而不会阻塞,所以你不必担心切换线程来更新 UI 或任何线程安全的东西)但这是做一个线程的基础.真的不知道那个代码实验室发生了什么。

    关于android - 如何在 Kotlin 中使用 Thread.sleep(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70646717/

    相关文章:

    android-studio - 您可以在Kotlin中使用自定义getter,默认setter和没有初始化程序声明属性吗?

    android - ImageView 上的绘图 : how to layout?

    Android ExpandableListView OnChildClickListener 不起作用

    java - Realm 生命周期 - 处理 android 中关闭/无效的实例

    android - 如何从PC到android仿真器获取UDP数据?

    maven - 像kotlin-gradle-plugin一样,如何将kotlin-js-library更新到1.1.3?

    android - 使用 SupportToolbar 进行手机布局,使用独立操作栏进行平板电脑布局

    android - 是否可以实例化一个 Activity 并向其添加 UI 元素,然后启动该实例?

    android - 如何观察协程流的 ContentProvider 变化

    android - 如何暂停 AsyncTask 以询问用户的详细信息?