Android Kotlin 基础知识:被调试简介搞糊涂了

Android Basics in Kotlin: confused by Introduction to Debugging

我有一个非常基本的问题。我正在按照建议的顺序阅读开发指南 codelabs,但在“调试介绍”第 6 节:“记录一个 运行 应用程序”时失败了。我发现解释非常混乱,因为对于初学者来说太简单了。

如果某些东西没有按预期工作,我很乐意删除并重新开始,但我还需要确保,随着我的进步,任何缺乏期望的结果都不是因为我的环境。

在本课中,我们需要修改现有代码以使用 Log.d 语句更新应用程序单个 TextView我们看到 ID division_textview 在 phone 屏幕上更新了。

我尝试了很多方法来添加最后的声明

findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}")

但不能将它添加到任何地方,以便在我的模拟器中更新值。我没有收到任何错误,但由于本课中没有“解决方案代码”,而且本课前面的图片都让最终代码的外观变得模糊不清,有人可以帮我解决这个问题吗?

我真的需要确保我的模拟器工作正常(没有报告错误)并且缺少结果是我的代码而不是我的设置。

这是有问题的课程(感谢您的提示!)

lesson

来自我的 MainActivity.kt 的代码进一步到下面的有用建议。请注意,我知道这不是 'optimal' 代码,此时我只是在尝试按照说明进行操作。

package com.example.debugging

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView

private const val TAG = "MainActivity"

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!"
        logging()
        division()
    }

    fun division() {
        val numerator = 60
        var denominator = 4
        repeat(4) {
            Thread.sleep(3)
            findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}")
            Log.v(TAG, "${numerator / denominator}")
            denominator--
        }
    }

    fun logging() {
            Log.e(TAG, "ERROR: a serious error like an app crash")
            Log.w(TAG, "WARN: warns about the potential for serious errors")
            Log.i(TAG, "INFO: reporting technical information, such as an operation succeeding")
            Log.d(TAG, "DEBUG: reporting technical information useful for debugging")
            Log.v(TAG, "VERBOSE: more verbose than DEBUG logs")
        }
    }

我认为这是一个写得非常草率和错误的教程。 (是的,即使它来自 Google。)如果你在主线程中休眠,在整个 repeat 循环完成之前你不会看到文本视图内容发生变化,所以你只会查看最终值,在 denominator 已经递减为 0 之后。此外,教程声称您将看到它每三秒更改一次,即使带有 Thread.sleep(3) 的代码只会暂停 3 秒。然后在他们的实际示例中,他们使用了 Thread.sleep(1),这与他们的说明相矛盾。

试试这个代码:

// added to imports:
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.*

// modified division function
fun division() = lifecycleScope.launch {
    val numerator = 60
    var denominator = 4
    repeat(4) {
        delay(3000)
        findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}")
        Log.v(TAG, "${numerator / denominator}")
        denominator--
    }
}

使用 = lifecycleScope.launch { 将您的函数变成协程,让您可以使用 delay() 函数而不是 Thread.sleep(),因此主线程有机会实际更新您的文本视图而不是必须等待整个 repeat 循环完成。


这里有另一种不用协程的方法,但不是那么漂亮:

fun division() = with(Handler(Looper.getMainLooper())) {
    val numerator = 60
    var denominator = 4
    repeat(4) { i ->
        postDelayed({
            findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}")
            Log.v(TAG, "${numerator / denominator}")
            denominator--
        }, i * 3000L)
    }
}