Android-HandlerThread使用及源碼分析

注:一次OPPO面試的尷尬瓣窄,所以回來(lái)惡補(bǔ)

原文鏈接借鑒

1 HandlerThread

1.1 主要作用

更簡(jiǎn)單的將一個(gè)一次性的多線程改進(jìn)成可以循環(huán)利用的異步線程(個(gè)人理解)

1.2 原理

繼承了Thread述寡,實(shí)際上是一個(gè)使用Looper、Handler的線程圣蝎。

繼承了Thread,在run()方法中通過(guò)Looper.prepare()來(lái)創(chuàng)建消息隊(duì)列栗竖,Looper.loop()來(lái)循環(huán)處理消息猫胁。

使用時(shí)開(kāi)啟HandlerThread,創(chuàng)建Handler與HandlerThread的Looper綁定涣澡,Handler以消息的方式通知HandlerThread來(lái)執(zhí)行一個(gè)具體的任務(wù)贱呐。

1.3 特點(diǎn)

HandlerThread將loop轉(zhuǎn)到子線程中處理,說(shuō)白了就是將分擔(dān)MainLooper的工作量入桂,降低了主線程的壓力奄薇,使主界面更流暢。

開(kāi)啟一個(gè)線程起到多個(gè)線程的作用抗愁。處理任務(wù)是串行執(zhí)行馁蒂,按消息發(fā)送順序進(jìn)行處理。HandlerThread本質(zhì)是一個(gè)線程蜘腌,在線程內(nèi)部远搪,代碼是串行處理的。

但是由于每一個(gè)任務(wù)都將以隊(duì)列的方式逐個(gè)被執(zhí)行到逢捺,一旦隊(duì)列中有某個(gè)任務(wù)執(zhí)行時(shí)間過(guò)長(zhǎng)谁鳍,那么就會(huì)導(dǎo)致后續(xù)的任務(wù)都會(huì)被延遲處理。

HandlerThread擁有自己的消息隊(duì)列劫瞳,它不會(huì)干擾或阻塞UI線程倘潜。

對(duì)于網(wǎng)絡(luò)IO操作,HandlerThread并不適合志于,因?yàn)樗挥幸粋€(gè)線程涮因,還得排隊(duì)一個(gè)一個(gè)等著。

HandlerThread內(nèi)部維護(hù)了一個(gè)消息隊(duì)列伺绽,避免多次創(chuàng)建和銷毀子線程來(lái)進(jìn)行操作养泡。

2 HandlerThread的使用

2.1 HandlerThread使用步驟

(1)創(chuàng)建HandlerThread實(shí)例,參數(shù)字符串定義新線程的名稱奈应。

HandlerThread mHandlerThread =newHandlerThread("check-message-coming");?

(2)啟動(dòng)HandlerThread線程澜掩。

mHandlerThread.start();

(3)創(chuàng)建Handler對(duì)象,將HandlerThread的Lopper作為參數(shù)杖挣,這樣就完成了Handler對(duì)象與HandlerThread的Looper對(duì)象的綁定(這里的Handler對(duì)象可以看作是綁定在HandlerThread子線程中肩榕,所以handlerMessage里的操作是在子線程中運(yùn)行的)。 重寫(xiě)handleMessage處理耗時(shí)操作惩妇。

Handler mCheckMsgHandler =newHandler(mHandlerThread.getLooper()){@OverridepublicvoidhandleMessage(Message msg){// 進(jìn)行耗時(shí)操作}};

這樣我們就可以使用mCheckMsgHandler對(duì)象以處理消息的形式來(lái)進(jìn)行耗時(shí)操作株汉,完成以后就可以切換到主線程的handler中來(lái)更新UI筐乳。

2.2 HandlerThread使用示例

依據(jù)剛才的步驟,來(lái)實(shí)現(xiàn)一個(gè)每秒更新數(shù)據(jù)的一個(gè)功能乔妈,這個(gè)功能可以用來(lái)更新股票蝙云、商品價(jià)格等。

創(chuàng)建和啟動(dòng)HandlerThread路召,handler綁定:新建Activity勃刨,在onCreate()中進(jìn)行使用一個(gè)initBackThread()方法創(chuàng)建HandlerThread。等待mCheckMsgHandler 得到消息開(kāi)始模擬耗時(shí)操作完成后切換到UI線程去更新UI优训,使用主線程的Handler也是一樣的。


綁定按鈕使用handler發(fā)送消息:一個(gè)開(kāi)始按鈕使mCheckMsgHandler發(fā)送消息去進(jìn)行耗時(shí)操作各聘,另一個(gè)按鈕停止發(fā)送消息揣非。標(biāo)記isUpdate設(shè)置是否再次發(fā)送消息更新。

要記得在onPause()和onDestroy()中暫停更新和停止mHandlerThread以釋放內(nèi)存躲因。

具體的源碼分析【轉(zhuǎn)載請(qǐng)注明出處:Android HandlerThread 源碼分析?CSDN 廢墟的樹(shù)】

HandlerThread源碼分析

HandlerThread構(gòu)造函數(shù)


分析:該類開(kāi)頭就給出了一個(gè)描述:該類用于創(chuàng)建一個(gè)帶Looper循環(huán)的線程早敬,Looper對(duì)象用于創(chuàng)建Handler對(duì)象,值得注意的是在創(chuàng)建Handler

對(duì)象之前需要調(diào)用start()方法啟動(dòng)線程大脉。這里可能有些人會(huì)有疑問(wèn)搞监?為啥需要先調(diào)用start()方法之后才能創(chuàng)建Handler呢?后面我們會(huì)解答镰矿。

上面的代碼注釋已經(jīng)很清楚了琐驴,HandlerThread類有兩個(gè)構(gòu)造方法,不同之處就是設(shè)置當(dāng)前線程的優(yōu)先級(jí)參數(shù)秤标。你可以根據(jù)自己的情況來(lái)設(shè)置優(yōu)先

級(jí)绝淡,也可以使用默認(rèn)優(yōu)先級(jí)。

HandlerThread的run方法


分析:以上代碼中的注釋已經(jīng)寫(xiě)得很清楚了苍姜,以上run方法主要作用就是調(diào)用了Looper.prepare和Looper.loop構(gòu)建了一個(gè)循環(huán)線程牢酵。值得一提的

是,run方法中在啟動(dòng)loop循環(huán)之前調(diào)用了onLooperPrepared方法衙猪,該方法的實(shí)現(xiàn)是一個(gè)空的馍乙,用戶可以在子類中實(shí)現(xiàn)該方法。該方法的作用是

在線程loop之前做一些初始化工作垫释,當(dāng)然你也可以不實(shí)現(xiàn)該方法丝格,具體看需求。由此也可以看出棵譬,Google工程師在編寫(xiě)代碼時(shí)也考慮到代碼的可擴(kuò)展性铁追。牛B!

HandlerThread的其他方法

getLooper獲得當(dāng)前線程的Looper對(duì)象



分析:其實(shí)方法開(kāi)頭的英文注釋已經(jīng)解釋的很清楚了:該方法主要作用是獲得當(dāng)前HandlerThread線程中的mLooper對(duì)象。

首先判斷當(dāng)前線程是否存活茫船,如果不是存活的琅束,這直接返回null扭屁。其次如果當(dāng)前線程存活的,在判斷線程的成員變量mLooper是否為null涩禀,如果為

null料滥,說(shuō)明當(dāng)前線程已經(jīng)創(chuàng)建成功,但是還沒(méi)來(lái)得及創(chuàng)建Looper對(duì)象艾船,因此葵腹,這里會(huì)調(diào)用wait方法去等待,當(dāng)run方法中的notifyAll方法調(diào)用之后

通知當(dāng)前線程的wait方法等待結(jié)束屿岂,跳出循環(huán)践宴,獲得mLooper對(duì)象的值。

總結(jié):在獲得mLooper對(duì)象的時(shí)候存在一個(gè)同步的問(wèn)題爷怀,只有當(dāng)線程創(chuàng)建成功并且Looper對(duì)象也創(chuàng)建成功之后才能獲得mLooper的值阻肩。這里等待方法wait和run方法中的notifyAll方法共同完成同步問(wèn)題。

quit結(jié)束當(dāng)前線程的循環(huán)


分析:以上有兩種讓當(dāng)前線程退出循環(huán)的方法运授,一種是安全的烤惊,一中是不安全的。至于兩者有什么區(qū)別? quitSafely方法效率比quit方法標(biāo)率低一點(diǎn)吁朦,但是安全柒室。具體選擇哪種就要看具體項(xiàng)目了。

總結(jié):

1.HandlerThread適用于構(gòu)建循環(huán)線程逗宜。

2.在創(chuàng)建Handler作為HandlerThread線程消息執(zhí)行者的時(shí)候必須調(diào)用start方法之后雄右,因?yàn)閯?chuàng)建Handler需要的Looper參數(shù)是從HandlerThread類中獲得,而Looper對(duì)象的賦值又是在HandlerThread的run方法中創(chuàng)建纺讲。

3.關(guān)于HandlerThread和Service的結(jié)合使用請(qǐng)參考另一篇博客:Android IntentService 源碼分析

【轉(zhuǎn)載請(qǐng)注明出處:Android HandlerThread源碼分析 CSDN 廢墟的樹(shù)】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末不脯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子刻诊,更是在濱河造成了極大的恐慌防楷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件则涯,死亡現(xiàn)場(chǎng)離奇詭異复局,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)粟判,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)亿昏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人档礁,你說(shuō)我怎么就攤上這事角钩。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵递礼,是天一觀的道長(zhǎng)惨险。 經(jīng)常有香客問(wèn)我,道長(zhǎng)脊髓,這世上最難降的妖魔是什么辫愉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮将硝,結(jié)果婚禮上恭朗,老公的妹妹穿的比我還像新娘。我一直安慰自己依疼,他們只是感情好痰腮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著律罢,像睡著了一般膀值。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弟翘,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天虫腋,我揣著相機(jī)與錄音骄酗,去河邊找鬼稀余。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趋翻,可吹牛的內(nèi)容都是我干的睛琳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼踏烙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼师骗!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起讨惩,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辟癌,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荐捻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體黍少,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年处面,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厂置。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡魂角,死狀恐怖昵济,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤访忿,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布瞧栗,位于F島的核電站,受9級(jí)特大地震影響醉顽,放射性物質(zhì)發(fā)生泄漏沼溜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一游添、第九天 我趴在偏房一處隱蔽的房頂上張望系草。 院中可真熱鬧,春花似錦唆涝、人聲如沸找都。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)能耻。三九已至,卻和暖如春亡驰,著一層夾襖步出監(jiān)牢的瞬間晓猛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工凡辱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戒职,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓透乾,卻偏偏與公主長(zhǎng)得像洪燥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乳乌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354