Handler的工作原理(消息機制)《開發(fā)藝術(shù)探索》
消息處理包括消息的發(fā)送與接收,發(fā)送分為send和post,而post本質(zhì)是由send實現(xiàn)的。
發(fā)送過程:
- 當handler.sendMessage后,MessageQueue的enqueueMessage會將消息入隊;
- MessageQueue的next()會將消息返回給Looper的loop()
- handler.dispatchMessage對消息進行處理
處理過程:
- 先檢查是否為post(通過msg.callback)
- 不是則判斷handler初始化是否傳入callback
- 沒有或處理失敗交由重寫的handleMessage處理
ThreadLocal(泛型)類
它是一個線程內(nèi)部的數(shù)據(jù)存儲類,通過它可以再指定線程中存取數(shù)據(jù),它是handler能獲取當前線程Looper的關(guān)鍵。雖然在不同線程中訪問的是同一個ThreadLocal對象(Looper類中有一個靜態(tài)最終變量sThreadLocal,記錄每個線程對應(yīng)的Looper),卻會獲得不一樣的值,這是因為真正存東西的是ThreadLocal類的靜態(tài)內(nèi)部類ThreadLocalMap,它的內(nèi)部還有個內(nèi)部類Entry建立了ThreadLocal實例和泛型的Map關(guān)系。ThreadLocal的set和get都是對Thread中的ThreadLocalMap變量的操作。像一種結(jié)構(gòu)型的設(shè)計模式,外觀模式。
Looper工作原理
它會不斷地從MessageQueue中查看是否有新消息,有則立即處理,沒有則阻塞。它在創(chuàng)建時會同時創(chuàng)建MessageQueue并保存當前thread信息。Looper.loop()在MessageQueue的next不返回消息而一直阻塞,若有返回則調(diào)用msg.target.dispatchMessage(msg)來處理消息,這里的dispatchMessage是在創(chuàng)建Hnadler時所使用的Looper中執(zhí)行的,因此將處理過程切換到了指定的線程。(其中msg.target為發(fā)送它的handler)
MessageQueue原理
主要包括兩個操作:插入和讀取,分別對應(yīng)enqueueMessage和next方法,enqueueMessage是向消息隊列中插入一條信息。next方法是一個循環(huán),若隊列中沒有消息,next方法會一直阻塞;當有新消息時,next會返回這條消息并從隊列中移除它
線程工具
Thread和Runnable
AsyncTack
HandlerThread
1、HandlerThread產(chǎn)生背景
當系統(tǒng)有多個耗時任務(wù)需要執(zhí)行時,每個任務(wù)都會開啟一個新線程去執(zhí)行耗時任務(wù),這樣會導(dǎo)致系統(tǒng)多次創(chuàng)建和銷毀線程,從而影響性能。為了解決這一問題,Google提供了HandlerThread,HandlerThread是在線程中創(chuàng)建一個Looper循環(huán)器,讓Looper輪詢消息隊列,當有耗時任務(wù)進入隊列時,則不需要開啟新線程,在原有的線程中執(zhí)行耗時任務(wù)即可,否則線程阻塞
2、HanlderThread的特點、
HandlerThread本質(zhì)上是一個線程,繼承自Thread
HandlerThread有自己的Looper對象,可以進行Looper循環(huán),可以創(chuàng)建Handler
HandlerThread可以在Handler的handlerMessage中執(zhí)行異步方法
HandlerThread優(yōu)點是異步不會堵塞,減少對性能的消耗
HandlerThread缺點是不能同時繼續(xù)進行多任務(wù)處理,需要等待進行處理,處理效率較低
HandlerThread與線程池不同,HandlerThread是一個串行隊列,背后只有一個線程
IntentService
1、IntentService是什么
IntentService是繼承自Service并處理異步請求的一個類,其內(nèi)部采用HandlerThread和Handler實現(xiàn)的,在IntentService內(nèi)有一個工作線程來處理耗時操作,其優(yōu)先級比普通Service高。當任務(wù)完成后,IntentService會自動停止,而不需要手動調(diào)用stopSelf()。另外,可以多次啟動IntentService,每個耗時操作都會以工作隊列的方式在IntentService中onHandlerIntent()回調(diào)方法中執(zhí)行,并且每次只會執(zhí)行一個工作線程
2、IntentService使用方法
創(chuàng)建Service繼承自IntentService
覆寫構(gòu)造方法和onHandlerIntent()方法
在onHandlerIntent()中執(zhí)行耗時操作