【多線程通信】消息機(jī)制Handler

Handler的工作原理(消息機(jī)制)《開(kāi)發(fā)藝術(shù)探索》

消息處理包括消息的發(fā)送與接收,發(fā)送分為send和post,而post本質(zhì)是由send實(shí)現(xiàn)的。

發(fā)送過(guò)程:

  1. 當(dāng)handler.sendMessage后,MessageQueue的enqueueMessage會(huì)將消息入隊(duì);
  2. MessageQueue的next()會(huì)將消息返回給Looper的loop()
  3. handler.dispatchMessage對(duì)消息進(jìn)行處理

處理過(guò)程:

  1. 先檢查是否為post(通過(guò)msg.callback)
  2. 不是則判斷handler初始化是否傳入callback
  3. 沒(méi)有或處理失敗交由重寫(xiě)的handleMessage處理

ThreadLocal(泛型)類(lèi)

它是一個(gè)線程內(nèi)部的數(shù)據(jù)存儲(chǔ)類(lèi),通過(guò)它可以再指定線程中存取數(shù)據(jù),它是handler能獲取當(dāng)前線程Looper的關(guān)鍵。雖然在不同線程中訪問(wèn)的是同一個(gè)ThreadLocal對(duì)象(Looper類(lèi)中有一個(gè)靜態(tài)最終變量sThreadLocal,記錄每個(gè)線程對(duì)應(yīng)的Looper),卻會(huì)獲得不一樣的值,這是因?yàn)檎嬲鏂|西的是ThreadLocal類(lèi)的靜態(tài)內(nèi)部類(lèi)ThreadLocalMap,它的內(nèi)部還有個(gè)內(nèi)部類(lèi)Entry建立了ThreadLocal實(shí)例和泛型的Map關(guān)系。ThreadLocal的set和get都是對(duì)Thread中的ThreadLocalMap變量的操作。像一種結(jié)構(gòu)型的設(shè)計(jì)模式,外觀模式。

Looper工作原理

它會(huì)不斷地從MessageQueue中查看是否有新消息,有則立即處理,沒(méi)有則阻塞。它在創(chuàng)建時(shí)會(huì)同時(shí)創(chuàng)建MessageQueue并保存當(dāng)前thread信息。Looper.loop()在MessageQueue的next不返回消息而一直阻塞,若有返回則調(diào)用msg.target.dispatchMessage(msg)來(lái)處理消息,這里的dispatchMessage是在創(chuàng)建Hnadler時(shí)所使用的Looper中執(zhí)行的,因此將處理過(guò)程切換到了指定的線程。(其中msg.target為發(fā)送它的handler)

MessageQueue原理

主要包括兩個(gè)操作:插入和讀取,分別對(duì)應(yīng)enqueueMessage和next方法,enqueueMessage是向消息隊(duì)列中插入一條信息。next方法是一個(gè)循環(huán),若隊(duì)列中沒(méi)有消息,next方法會(huì)一直阻塞;當(dāng)有新消息時(shí),next會(huì)返回這條消息并從隊(duì)列中移除它

線程工具

Thread和Runnable

AsyncTack

HandlerThread

1、HandlerThread產(chǎn)生背景

當(dāng)系統(tǒng)有多個(gè)耗時(shí)任務(wù)需要執(zhí)行時(shí),每個(gè)任務(wù)都會(huì)開(kāi)啟一個(gè)新線程去執(zhí)行耗時(shí)任務(wù),這樣會(huì)導(dǎo)致系統(tǒng)多次創(chuàng)建和銷(xiāo)毀線程,從而影響性能。為了解決這一問(wèn)題,Google提供了HandlerThread,HandlerThread是在線程中創(chuàng)建一個(gè)Looper循環(huán)器,讓Looper輪詢消息隊(duì)列,當(dāng)有耗時(shí)任務(wù)進(jìn)入隊(duì)列時(shí),則不需要開(kāi)啟新線程,在原有的線程中執(zhí)行耗時(shí)任務(wù)即可,否則線程阻塞

2、HanlderThread的特點(diǎn)、

HandlerThread本質(zhì)上是一個(gè)線程,繼承自Thread
HandlerThread有自己的Looper對(duì)象,可以進(jìn)行Looper循環(huán),可以創(chuàng)建Handler
HandlerThread可以在Handler的handlerMessage中執(zhí)行異步方法
HandlerThread優(yōu)點(diǎn)是異步不會(huì)堵塞,減少對(duì)性能的消耗
HandlerThread缺點(diǎn)是不能同時(shí)繼續(xù)進(jìn)行多任務(wù)處理,需要等待進(jìn)行處理,處理效率較低
HandlerThread與線程池不同,HandlerThread是一個(gè)串行隊(duì)列,背后只有一個(gè)線程

IntentService

1、IntentService是什么

IntentService是繼承自Service并處理異步請(qǐng)求的一個(gè)類(lèi),其內(nèi)部采用HandlerThread和Handler實(shí)現(xiàn)的,在IntentService內(nèi)有一個(gè)工作線程來(lái)處理耗時(shí)操作,其優(yōu)先級(jí)比普通Service高。當(dāng)任務(wù)完成后,IntentService會(huì)自動(dòng)停止,而不需要手動(dòng)調(diào)用stopSelf()。另外,可以多次啟動(dòng)IntentService,每個(gè)耗時(shí)操作都會(huì)以工作隊(duì)列的方式在IntentService中onHandlerIntent()回調(diào)方法中執(zhí)行,并且每次只會(huì)執(zhí)行一個(gè)工作線程

2、IntentService使用方法

創(chuàng)建Service繼承自IntentService
覆寫(xiě)構(gòu)造方法和onHandlerIntent()方法
在onHandlerIntent()中執(zhí)行耗時(shí)操作

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

相關(guān)閱讀更多精彩內(nèi)容

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