一、什么是handler?
? ? 答:handler是Android給我們提供用來更新UI的一套機(jī)制,也是一套消息處理機(jī)制,我們可以發(fā)消息,也可以通過它 處理消息。
二、那為什么要用handler呢?我能不能不用?
答:我在網(wǎng)上搜了下,給我的答案是,肯定是不行的。因為android在設(shè)計的時候就封裝了一套消息創(chuàng)建、傳遞、處理。如果不遵循就不能更新UI信息,就會報出異常。
三、Android為什么要設(shè)計只能用handler機(jī)制更新UI呢?
? ? 答:最根本的目的就是為了解決多線程并發(fā)的問題!
? ? ? ? ? ?打個比方,如果在一個activity中有多個線程,并且沒有加鎖,就會出現(xiàn)界面錯亂的問題。但是如果對這些更新UI的操作都加鎖處理,又會導(dǎo)致性能下降。
? ? ? ? ? 處于對性能的問題考慮,Android給我們提供這一套更新UI的機(jī)制我們只需要遵循這種機(jī)制就行了。不用再去關(guān)系多線程的問題,所有的更新UI的操作,都是在主線程的消息隊列中去輪訓(xùn)的。
四、handler、Looper、MessageQueue的原理是什么?
? ? 答:大家都知道handler的作用有兩個,發(fā)送消息和處理消息。而handler發(fā)送的消息必須被送到指定MessageQueue(消息隊列)中,也就是說,如果想讓handler正常工作,就必須有一個MessageQueue(消息隊列),不過MessageQueue(消息隊列)是由Looper來關(guān)系。所以也可以說想讓handler正常工作,必須在當(dāng)前線程中有一個Looper對象。(請認(rèn)真讀)
1、來看一下Looper提供的構(gòu)造器源碼,如圖:

你會發(fā)現(xiàn)該構(gòu)造器用到的是private(私有化),告訴你的就是程序員你不能通過構(gòu)造方法創(chuàng)建looper對象,而在方法中Looper創(chuàng)建了一個與關(guān)聯(lián)的MessageQueue,這個MessageQueue就是用來管理Message(handler接收和處理的消息對象)!
2、為了保證當(dāng)前線程有Looper對象,可以有兩種情況處理。(瘋狂的Android講義224頁)
? ?(1)主ui線程啟動,系統(tǒng)就初始化了一個Looper對象,只要在程序中直接創(chuàng)建handler即可,然后用handler發(fā)送和處理消息。
? ?(2)程序員自己創(chuàng)建的線程,這個時候就要自己手動創(chuàng)建一個Looper對象了,創(chuàng)建Looper對象調(diào)用它的prepare()。prepare()方法 ? ? ? ? ? ? ?是為了保證每個線程最多一個Looper對象。
? ? ??prepare()方法?源碼如圖。

? ? 然后用Looper.loop()啟動它。此時loop()方法就會使用一個死循環(huán)不斷地取出MessageQueue()中的消息,并將消息分給所對應(yīng)的Handler處理。
?好吧總結(jié)一下吧:
? ?:Looper的作用:每個線程只有一個Looper,他負(fù)責(zé)管理MessageQueue,會不斷的從MessageQueue取出消息,分發(fā)給對象 ? ? ? ? ? ? ?的handler
? ?:MessageQueue的作用:由Looper管理,而MessageQueue則采用先進(jìn)的方法來管理Message!
? ?:Handler的作用:它把消息發(fā)送給Looper管理的MessageQueue,并負(fù)責(zé)處理Looper分發(fā)給他的消息。
六、Android在子線程更新UI的最常見的五種方式 (這里不講解AsyncTask(異步任務(wù)))
?? ? 1、runOnUiThread()方法

? ? ?2、handler.post()方法

?3、handler.sendMessage()方法

? ? ?4、view.post()方法。

? ? ?5、view postDelayed(Runnable,long)
? ? ? 前四種是慕課網(wǎng)老師講解的,最后一種是瘋狂Android講義書籍上有的一種。如果想要詳細(xì)了解,請點擊鏈接:點擊打開鏈接http://www.imooc.com/video/5725/0(慕課網(wǎng)講的很詳細(xì),希望幫助到大家)。
六、非UI線程真的不能跟新UI嗎?
答:對著這個問題我就開始百度、查書籍、最后看慕課網(wǎng),好吧!終于得到答案,答案就是:有些時候是可以更新UI的,在ViewRootImpl沒有實例化的時候是不會check是否是主線程,也就是說,在非UI線程中是可以更新UI的。