在子線程中使用Toast拋出異常坐桩,提示錯(cuò)誤顯示:Can't create handler inside thread that has not called Looper.prepare().
ActivityThread和ViewRootImpl分析到底什么叫子線程不能更新UI。
Toast本質(zhì)上是一個(gè)window封锉,跟activity是平級(jí)的绵跷,checkThread只是Activity維護(hù)的View樹的行為膘螟。
Toast使用的無所謂是不是主線程Handler,吐司操作的是window碾局,不屬于checkThread拋主線程不能更新UI異常的管理范疇荆残。它用Handler只是為了用隊(duì)列和時(shí)間控制排隊(duì)顯示吐司。
即使是子線程净当,先Looper.prepare,再show吐司内斯,再Looper.loop一樣可以吐出來,只不過loop操作會(huì)阻塞這個(gè)線程像啼,沒人這么玩罷了俘闯,都是讓Toast用主線程的Handler,這個(gè)是在ActivityThread里初始化的忽冻,本來就是阻塞處理所有的UI交互邏輯备徐。
new Thread(){
public void run(){
Looper.prepare();//給當(dāng)前線程初始化Looper
// Toast初始化的時(shí)候會(huì)new Handler();無參構(gòu)造默認(rèn)獲取當(dāng)前線程的Looper,
// 如果沒有prepare過甚颂,則拋出題主描述的異常。上一句代碼初始化過了秀菱,就不會(huì)出錯(cuò)振诬。
Toast.makeText(getApplicationContext(),"你猜我能不能彈出來~~",0).show();
// 這句執(zhí)行,Toast排隊(duì)show所依賴的Handler發(fā)出的消息就有人處理了衍菱,
// Toast就可以吐出來了赶么。但是,這個(gè)Thread也阻塞這里了脊串,因?yàn)閘oop()是個(gè)for (;;) ...
Looper.loop();
}
}.start();