Handler詳解(最容易看懂,最容易理解)
好吧好吧,今天去面試的時候,一個熊二般的面試官問我handler的機制,以及和Looper的關係,以及更新UI有哪些方式。可是我是小白啊,所以不知道,所以就不可能通過面試,不過今年工作可真不好找。回來後又是把書籍,又是看視訊,最終還是打算寫成自己的部落格。希望幫助到其他的小白。
下面我們通過六大模組來了解下handler相關內容(有錯誤幫忙點出來,謝謝大家。我的理解還很片面和淺薄!)
一、什麼是handler?
答:handler是Android給我們提供用來更新UI的一套機制,也是一套訊息處理機制,我們可以發訊息,也可以通過它 處理訊息。
二、那為什麼要用handler呢?我能不能不用?
答:我在網上搜了下,給我的答案是,肯定是不行的。因為android在設計的時候就封裝了一套訊息建立、傳遞、處理。如果不遵循就不能更新UI資訊,就會報出異常。
三、Android為什麼要設計只能用handler機制更新UI呢?
答:最根本的目的就是為了解決多執行緒併發的問題!
打個比方,如果在一個activity中有多個執行緒,並且沒有加鎖,就會出現介面錯亂的問題。但是如果對這些更新UI的操作都加鎖處理,又會導致效能下降。
處於對效能的問題考慮,Android給我們提供這一套更新UI的機制我們只需要遵循這種機制就行了。不用再去關係多執行緒的問題,所有的更新UI的操作,都是在主執行緒的訊息佇列中去輪訓的。
四、handler、Looper、MessageQueue的原理是什麼?
答:大家都知道handler的作用有兩個,傳送訊息和處理訊息。而handler傳送的訊息必須被送到指定MessageQueue(訊息佇列)中,也就是說,如果想讓handler正常工作,就必須有一個MessageQueue(訊息佇列),不過MessageQueue(訊息佇列)是由Looper來關係。所以也可以說想讓handler正常工作,必須在當前執行緒中有一個Looper物件。(請認真讀)
1、來看一下Looper提供的構造器原始碼,如圖:
你會發現該構造器用到的是private(私有化),告訴你的就是程式設計師你不能通過構造方法建立looper物件,而在方法中Looper建立了一個與關聯的MessageQueue,這個MessageQueue就是用來管理Message(handler接收和處理的訊息物件)!
2、為了保證當前執行緒有Looper物件,可以有兩種情況處理。(瘋狂的Android講義224頁)
(1)主ui執行緒啟動,系統就初始化了一個Looper物件,只要在程式中直接建立handler即可,然後用handler傳送和處理訊息。
(2)程式設計師自己建立的執行緒,這個時候就要自己手動建立一個Looper物件了,建立Looper物件呼叫它的prepare()。prepare()方法 是為了保證每個執行緒最多一個Looper物件。
prepare()方法 原始碼如圖。
然後用Looper.loop()啟動它。此時loop()方法就會使用一個死迴圈不斷地取出MessageQueue()中的訊息,並將訊息分給所對應的Handler處理。
好吧總結一下吧:
:Looper的作用:每個執行緒只有一個Looper,他負責管理MessageQueue,會不斷的從MessageQueue取出訊息,分發給物件 的handler
:MessageQueue的作用:由Looper管理,而MessageQueue則採用先進的方法來管理Message!
:Handler的作用:它把訊息傳送給Looper管理的MessageQueue,並負責處理Looper分發給他的訊息。
六、Android在子執行緒更新UI的最常見的五種方式 (這裡不講解AsyncTask(非同步任務))
1、runOnUiThread()方法
2、handler.post()方法
3、handler.sendMessage()方法
4、view.post()方法。
5、view postDelayed(Runnable,long)
(慕課網講的很詳細,希望幫助到大家)。
六、非UI執行緒真的不能跟新UI嗎?
答:對著這個問題我就開始百度、查書籍、最後看慕課網,好吧!終於得到答案,答案就是:有些時候是可以更新UI的,在ViewRootImpl沒有例項化的時候是不會check是否是主執行緒,也就是說,在非UI執行緒中是可以更新UI的。至於具體理論,我把下面的視訊地址給貼上以方便小夥伴更詳細的瞭解。點選開啟連結(http://www.imooc.com/video/5726)!因為我自己沒怎麼看懂,好丟臉!
好吧,對於Handler就說到這裡吧,可能講的很籠統,因為自己技術能力原因,所以希望大家諒解,也希望大家自己去看視訊和書籍或者自己寫個小程式加深印象。(一邊查一遍總結,寫了3個小時,自己的能力還是太爛了,哎!)