在子線程中使用Toast拋出異常,提示錯誤顯示:Can't create handler inside thread that has not called Looper.prepare().
ActivityThread和ViewRootImpl分析到底什么叫子線程不能更新UI。
Toast本質上是一個window,跟activity是平級的,checkThread只是Activity維護的View樹的行為。
Toast使用的無所謂是不是主線程Handler,吐司操作的是window,不屬于checkThread拋主線程不能更新UI異常的管理范疇。它用Handler只是為了用隊列和時間控制排隊顯示吐司。
即使是子線程,先Looper.prepare,再show吐司,再Looper.loop一樣可以吐出來,只不過loop操作會阻塞這個線程,沒人這么玩罷了,都是讓Toast用主線程的Handler,這個是在ActivityThread里初始化的,本來就是阻塞處理所有的UI交互邏輯。
new Thread(){
public void run(){
Looper.prepare();//給當前線程初始化Looper
// Toast初始化的時候會new Handler();無參構造默認獲取當前線程的Looper,
// 如果沒有prepare過,則拋出題主描述的異常。上一句代碼初始化過了,就不會出錯。
Toast.makeText(getApplicationContext(),"你猜我能不能彈出來~~",0).show();
// 這句執行,Toast排隊show所依賴的Handler發出的消息就有人處理了,
// Toast就可以吐出來了。但是,這個Thread也阻塞這里了,因為loop()是個for (;;) ...
Looper.loop();
}
}.start();