Android Handler 機制

 Handler機制在Android多線程編程中可以說是不可或缺的角色,也是必須掌握的內(nèi)容,所以深入掌握并應(yīng)用Handler異步處理機制在Android開發(fā)中顯得特別重要。它在使用的過程中主要與Messgae、MessageQueue、和Looper這三個對象關(guān)聯(lián)密切,Handler機制的實現(xiàn)原理依賴于這三者

在Android中Handler常用于在子線程發(fā)送結(jié)果,然后通知在主線程中刷新視圖界面。

Message為消息的載體,這個類實現(xiàn)了Parcelable借口,Message中含有what,arg1,arg2,obj,target等成員變量,what常用來作為一個標(biāo)志,消息數(shù)據(jù)則是放在obj中,Message.obtain()方法生成一個Message對象。

Looper是線程用來運行消息循環(huán)(message loop)的類。常用的方法為Looper.prepare()和Looper.loop()。Looper.prepare()用于生成一個Looper對象,Looper.loop()用于無限循環(huán)分發(fā)MessageQueue中的消息。主線程中Looper是應(yīng)用啟動時候系統(tǒng)主動的創(chuàng)建的。子線程可以通過Looper.prepare()來創(chuàng)建,一個線程中只能存在一個Looper。

MessageQueue是一個消息隊列,通過單鏈路數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)的,用于存儲消息的集合。主要方法有:enqueueMessage(Messagemsg, long when),插入消息,next(),取出消息,quit(),關(guān)閉。其中next()是個阻塞方法,里面是一個無限for不斷的取消息,如果存在消息便取出,否則便阻塞,主線程便會釋放CPU資源進入休眠狀態(tài),直到下個消息到達(dá)或者有事務(wù)發(fā)生時,才通過往pipe管道寫端寫入數(shù)據(jù)來喚醒主線程工作。主線程中MessageQueue是創(chuàng)建Looper的時候創(chuàng)建的,所以使用主線程中的Handler時候,不需要自己去創(chuàng)建。

Handler?

1.Handler()?默認(rèn)構(gòu)造方法,與當(dāng)前線程及其Looper實例綁定。如在主線程中執(zhí)行new Handler(),那么該handler實例所綁定的便是 UI 線程和 UI 線程綁定的Looper實。

2.Handler(Callback callback)自定義一個回調(diào)方法。

3.Handler(Looper looper)自己傳入一個Looper對象。

不過所有的構(gòu)造方法最后都會調(diào)用Handler(Looper looper, Callback callback, boolean async);

Handler中常用的方法:

^post(Runnable):將runnable對象入隊。

^postAtTime(Runnable, long):將runnable對象入隊,并在指定時間執(zhí)行

^postDelayed(Runnable, long):將runnable對象入隊,并經(jīng)過指定時間后執(zhí)行。

^sendEmptyMessage(int):發(fā)送只具有what標(biāo)志值得message。

^sendMessage(Message):將一個message對象入隊,且允許該message對象帶有一些數(shù)據(jù),如一個bundle類型的數(shù)據(jù)或一個int類型的標(biāo)志值等,這些數(shù)據(jù)將在Handler的handleMessage(Message) 方法中進行處理,當(dāng)然,具體處理邏輯需要我們自己重寫handleMessage()方法。

^sendMessageDelayed(Message, long):將message入隊,并在當(dāng)前時間延遲指定時間長度前將該消息放在所有掛起的消息之后。

^sendMessageAtTime(Message, long):將message入隊,并在指定時間到之前將該消息放在所有掛起的消息之后。

以上便是比較常用的方法,并且可以看出上面的所有方法最終調(diào)用的都是sendMessageAtTime(Message, long)?這個方法(如果傳入的參數(shù)是runnable的話,會先調(diào)用getPostMessage(Runnable)?或getPostMessage(Runnable, Object)方法獲取消息),然后由sendMessageAtTime(Message, long)?為message對象指定target為該handler實例,并返回一個enqueueMessage(MessageQueue, Message, long)?方法,該方法如下,最終通過MessageQueue的enqueueMessage(Message, long)?將消息成功送進消息隊列中。

使用流程的話:一般先創(chuàng)建一個Handler,然后在子線程工作完成后,通過Message打包數(shù)據(jù),使用handler對象發(fā)送,最后在Handler中處理子線程發(fā)送過來的結(jié)果。一個線程中只能存在一個Looper和MessageQueue,但可以存在多個Handler,Handler可以跨線程使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容