關(guān)于 Handler 的內(nèi)存泄露及處理方法

前言

今天在看程序員每天面試一題夫椭,看到了這樣的一個(gè)面試題:關(guān)于 Handler 的內(nèi)存泄露劣欢,及怎么樣處理?

這是一個(gè)老生常談的問題湿弦,網(wǎng)上也是有很多文章講解瓤漏。而且大部分的講解都是大同小異,所以如果你已經(jīng)了解過了那基本可以不用看本篇了颊埃。

寫下來的主要目的是記錄一下自己的了解蔬充、所得。

Part1

為什么會(huì)泄露班利?

要講為什么會(huì)泄露饥漫,那就要從 Handler 的工作機(jī)制開始講起

1.Android 的主線程在一開始啟動(dòng)的時(shí)候就已經(jīng)默認(rèn)的常見了一個(gè) Looper 實(shí)例了,這個(gè)實(shí)例主要是用于處理一個(gè)一個(gè)的處理消息隊(duì)列中的 Message,它的生命周期是跟整個(gè)應(yīng)用的生命周期一樣長(zhǎng)的罗标。

2.當(dāng)我們使用 Handler 發(fā)送一個(gè) Message 到Looper 處理的消息隊(duì)列的時(shí)候趾浅,這個(gè) Message就已經(jīng)包含了改 handler 的實(shí)例了,這樣 Looper在處理到該 Message 的時(shí)候才可以調(diào)用 handler.handlerMessage()馒稍。

3.在Java 的非靜態(tài)內(nèi)部類或匿名內(nèi)部類會(huì)隱式持有外部類的實(shí)例皿哨。

so,在發(fā)送出去的 Message 還沒有被處理之前纽谒,該 Message 持有的 Handler 就不會(huì)被回收证膨,導(dǎo)致該Handler所在的外部類也不會(huì)回收。

Talk is cheep , show me the code! 無 code 言屌~

假設(shè)我們?cè)?Activity 發(fā)送了這樣的一個(gè) Message:


在 Activi 創(chuàng)建的時(shí)候發(fā)送一個(gè)定時(shí)十分鐘的消息鼓黔,此時(shí)在十分鐘還沒有到的時(shí)候央勒,我們按 Back 鍵,或者調(diào)用 finish結(jié)束當(dāng)前的 Activity澳化,該 Activity 其實(shí)并不會(huì)被回收崔步,因?yàn)樗膶?shí)例被 handler 隱式持有了,而 handler 又被 message 持有缎谷,此時(shí) message 又安安靜靜的躺在 Looper 的消息隊(duì)列中等待時(shí)間到被處理井濒。所以這樣子內(nèi)存泄露了。

Part2

how to fix列林?

既然知道是了非靜態(tài)內(nèi)部類或者匿名內(nèi)部類持有外部類而引起的瑞你,那么我們肯定就是從這方面入手了。

1.把 Handler 放在單獨(dú)的類文件希痴,或者使用靜態(tài)內(nèi)部類者甲,這樣避免持有外部類引用。

2.在靜態(tài)內(nèi)部類或是單獨(dú)的類文件中需要用到外部類的時(shí)候砌创,用弱引用來處理虏缸,在使用時(shí)再對(duì)該引用進(jìn)行 null 判斷

3.另外關(guān)于同樣也需要將Runnable設(shè)置為靜態(tài)的成員屬性

那么照著這樣的思路鲫懒,修改之后的代碼如下:


在經(jīng)過修改之后,handler 就不會(huì)持有 activity 的應(yīng)用刽辙,這樣子 Activity 該被干掉還是會(huì)被干掉窥岩,改回收的東西照樣會(huì)回收。

by the way:

在 handler中一定要重寫 handleMessage()然后一定要進(jìn)行非空判斷扫倡。

不然定時(shí)到了,Looper 調(diào)用了 message 的 handler.handleMessage(),然后就會(huì) nullPointException 竟纳,APP 就會(huì) crash了~

如果這篇文章又幫到你的話撵溃,請(qǐng)點(diǎn)一下‘喜歡’,我會(huì)更努力的創(chuàng)作的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锥累,一起剝皮案震驚了整個(gè)濱河市缘挑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桶略,老刑警劉巖语淘,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異际歼,居然都是意外死亡惶翻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門鹅心,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吕粗,“玉大人,你說我怎么就攤上這事旭愧÷睿” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵输枯,是天一觀的道長(zhǎng)议泵。 經(jīng)常有香客問我,道長(zhǎng)桃熄,這世上最難降的妖魔是什么先口? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮瞳收,結(jié)果婚禮上池充,老公的妹妹穿的比我還像新娘。我一直安慰自己缎讼,他們只是感情好收夸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著血崭,像睡著了一般卧惜。 火紅的嫁衣襯著肌膚如雪厘灼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音卵史,去河邊找鬼沼琉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闪朱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钻洒,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼奋姿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了素标?” 一聲冷哼從身側(cè)響起称诗,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎头遭,沒想到半個(gè)月后寓免,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡计维,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年袜香,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲫惶。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡困鸥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剑按,到底是詐尸還是另有隱情疾就,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布艺蝴,位于F島的核電站猬腰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏猜敢。R本人自食惡果不足惜姑荷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缩擂。 院中可真熱鬧鼠冕,春花似錦、人聲如沸胯盯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽博脑。三九已至憎乙,卻和暖如春票罐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泞边。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工该押, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阵谚。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓蚕礼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親梢什。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奠蹬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容