如何使用Thread和Handler(kotlin)

如何使用Thread和Handler(kotlin)

情境

無痛執行緒裡面講到,如果你要在 Worker Thread 上執行任務時,不可以更新 UI,否則會跳出以下訊息且閃退。

  • android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

另外一個點就是不能在 Main Thread 上處理比較冗長的任務,否則也會跳出 ANR(Application Not Responding) 視窗。

完整程式碼

如果你需要完整程式碼,可以到 GitHub 上觀看或下載。

程式碼說明

如果你想要製造 Crash 可以透過以下方式來進行

show_msg.setOnClickListener {
	Thread {  
		text_view.text = "click"  
	}.start()
}

當我們按下去 Button 按鈕馬上就會閃退,並且出現以下訊息。

  • android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

如果你想要製造 ANR 視窗,可以透過以下程式碼產生。

show_msg.setOnClickListener {
	while(true){  
	    text_view.text = "click"  
	}
}

ANR 視窗如下。


如果我們需要在一個冗長的任務上頻繁的更新 UI 該怎麼處理呢? 我們可以透過 Handler 幫我們處理這件事情。

show_msg.setOnClickListener {  
	Thread {  
		for (i in 1..10) {  
			val message = Message()  
			message.what = 1  
			handler.sendMessage(message)  
			Thread.sleep(1000)  
		}  
	}.start()  
}

宣告一個 Message 的物件,並且自己定義一個常數丟給 what 參數,這時候就需要 Handler 來幫忙一下,
Handler 專門用來告知你的程式說:你的執行緒跑完了,該更新一下畫面了喔!
所以利用 Handler 把這個 message send 出去處理,並且每 1 秒就送一次訊息。

var index = 0  
val handler = Handler {  
	if (it.what == 1) {  
		index++  
		text_view.text = "number: $index"  
	}  
	true  
}

我們宣告一個變數 i ,一開始為 0
如果接收到一次的訊息,我們就把變數加 1
然後更新 TextView 的畫面,這樣 TextView 就會像計數器一樣慢慢地累加上去。



這樣就是一個簡單的操作 Handler 的範例。