這來自在此處找到的代碼實驗室的末尾附近:
除錯簡介 - 除錯示例:訪問不存在的值
這都在 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 秒的間隔發生。
為什么布局在等待,如何讓它在回圈的每次迭代中更新?
uj5u.com熱心網友回復:
老實說,根據他們提供的代碼,我不知道 Codelab 在做什么。該應用程式在onCreate完成之前不會渲染任何東西(不是布局,也不是??對布局的任何更改),并且onCreate在它運行所有代碼之前不會完成,包括它呼叫repeat的division函式中的那個塊。
division沒有啟動任何作業執行緒,所以Thread.sleep所做的只是阻塞主執行緒 - 它正在掛起應用程式。你是對的,sleep確實需要一個毫秒值,而不是秒 - 我覺得他們實際上并沒有運行這段代碼,它充滿了其他錯誤和不一致,老實說很難弄清楚你打算做什么. 換哪個Log.d電話?onCreate 中的那些?(他們實際上是指Log.v打電話division,我想)
以下是您在 Kotlin 中使用執行緒的方式 - 您需要創建一個新執行緒(這樣您就離開了主執行緒,因此它實際上可以完成創建活動并運行 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為簡潔起見,這只是使用當前的重復編號 ( ) 進行更新,但重要的是:
- 您正在創建一個新執行緒來完成作業(并且正在睡覺)
- 您正在使用
runOnUiThread(這是 Activity 上的一種方法)在主/UI 執行緒上進行文本更新(同樣的事情)。如果您嘗試從另一個執行緒觸摸 UI,它將崩潰
您可以做到這一點的另一種方法是post通過視圖運行到 UI 執行緒,也可以使用它TextView:
divisionTextView.post { divisionTextView.text = "$i" }
協程在這里是一個更好的主意(你可以在主執行緒上運行它們而不會阻塞,所以你不必擔心切換執行緒來更新 UI 或任何執行緒安全的東西)但這是做一個執行緒的基礎. 真的不知道那個代碼實驗室發生了什么。
uj5u.com熱心網友回復:
在 repeat() 完成之前,螢屏上不會顯示任何內容,甚至是應用程式的名稱。正如預期的那樣,日志以 3 秒的間隔發生。為什么布局等待?
這是由于Activity生命周期
- 當 Activity 處于 Created 狀態時,您看不到 UI。
- 當 Activity 處于 Started 狀態時,UI 變為可見,但您無法與之互動。
- 當 Activity 處于 Resumed 狀態時,UI 是可見的并且您可以與之互動。
由于您在 onCreate() 回呼中呼叫了 division() 函式,因此您不會看到活動 UI。
如何讓它在回圈的每次迭代中更新?
一種方法是在新執行緒中運行您的 division() 函式。通過這樣做,主踏板會顯示 UI(您將看不到它)。然后使用 runOnUiThread 更新您的 division_textview 文本。
fun division() {
val numerator = 60
var denominator = 4
thread(start=true) {
/* The loop only repeat 4 times to avoid a crash*/
repeat(4) {
Log.v(TAG, "$denominator")
// Set division_textview text to the quotient.
runOnUiThread { findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}") }
// Wait for 1 second
Thread.sleep(1000L)
denominator--
}
}
}
uj5u.com熱心網友回復:
嘗試使用協程。這是一個鏈接:https : //kotlinlang.org/docs/coroutines-basics.html
uj5u.com熱心網友回復:
您可以使用協程。延遲功能非常好用
lifecycleScope.launch {
myTextView.text = "Starting"
delay(1000L)
myTextView.text = "Processing"
delay(2000L)
myTextView.text = "Done"
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/409178.html
標籤:
