Handler,Message,looper 和 MessageQueue 構(gòu)成了安卓的消息機制,handler創(chuàng)建后可以通過 sendMessage 將消息加入消息隊列,然后 looper不斷的將消息從 MessageQueue 中取出來,回調(diào)到 Hander 的 handleMessage方法,從而實現(xiàn)線程的通信。
從兩種情況來說,第一在UI線程創(chuàng)建Handler,此時我們不需要手動開啟looper,因為在應用啟動時,在ActivityThread的main方法中就創(chuàng)建了一個當前主線程的looper,并開啟了消息隊列,消息隊列是一個無限循環(huán),為什么無限循環(huán)不會ANR?因為可以說,應用的整個生命周期就是運行在這個消息循環(huán)中的,安卓是由事件驅(qū)動的,Looper.loop不斷的接收處理事件,每一個點擊觸摸或者Activity每一個生命周期都是在Looper.loop的控制之下的,looper.loop一旦結(jié)束,應用程序的生命周期也就結(jié)束了。我們可以想想什么情況下會發(fā)生ANR,第一,事件沒有得到處理,第二,事件正在處理,但是沒有及時完成,而對事件進行處理的就是looper,所以只能說事件的處理如果阻塞會導致ANR,而不能說looper的無限循環(huán)會ANR
另一種情況就是在子線程創(chuàng)建Handler,此時由于這個線程中沒有默認開啟的消息隊列,所以我們需要手動調(diào)用looper.prepare(),并通過looper.loop開啟消息
主線程Looper從消息隊列讀取消息,當讀完所有消息時,主線程阻塞。子線程往消息隊列發(fā)送消息,并且往管道文件寫數(shù)據(jù),主線程即被喚醒,從管道文件讀取數(shù)據(jù),主線程被喚醒只是為了讀取消息,當消息讀取完畢,再次睡眠。因此loop的循環(huán)并不會對CPU性能有過多的消耗。