1.Handler 引起的內(nèi)存泄漏
Handler是Andorid給我們提供的一套UI更新機(jī)制秩霍,同時(shí)它也是一套消息處理機(jī)制舆乔。
使用Handler消息處理機(jī)制在多個(gè)線程并發(fā)更新UI的同時(shí) 采郎,可以保證線程安全荚守。
先看看下圖:
出現(xiàn)了一大片黃色警告端铛,what每聪?怎么回事的旦棉。黃色警告的大概意思:Handler可能會(huì)內(nèi)存泄漏,推薦使用靜態(tài)內(nèi)部類+實(shí)例化弱引用药薯。在使用Handler時(shí)如果直接使用匿名內(nèi)部類的方式創(chuàng)建Handler對(duì)象IDE會(huì)發(fā)出警告绑洛,提示內(nèi)存泄漏風(fēng)險(xiǎn)。非靜態(tài)的內(nèi)部類和匿名類會(huì)隱式地持有一個(gè)他們外部類的引用童本。靜態(tài)內(nèi)部類則不會(huì)真屯。
上圖的Handler正是通過(guò)內(nèi)部類創(chuàng)建的,它可能會(huì)阻止外部類被垃圾收集(假如上圖的程序代碼是在Activity類里創(chuàng)建的穷娱,就算關(guān)閉了Activity绑蔫,Activity還是無(wú)法被回收的)。
如果程序代碼對(duì)主線程以外的線程使用循環(huán)程序或MessageQueue泵额,就沒(méi)什么問(wèn)題配深。但是如果程序代碼使用到了主線程的Looper或MessageQueue,則很可能會(huì)導(dǎo)致內(nèi)存泄漏嫁盲。有以下解決方案:
方法一:
添加這個(gè) @SuppressLint("HandlerLeak")注解篓叶,防止由handler引起的內(nèi)存溢出,此時(shí)黃色警告就沒(méi)有了。
方法二:
在實(shí)例化Handler時(shí)可以使用回調(diào)接口缸托,以避免必須實(shí)現(xiàn)自己的Handler子類左敌。如下圖:
方法三:
使用靜態(tài)內(nèi)部類+實(shí)例化弱引用
(ps:? Handler可以發(fā)送和處理消息對(duì)象或Runnable對(duì)象,這些消息對(duì)象和Runnable對(duì)象與一個(gè)線程相關(guān)聯(lián)俐镐。每個(gè)Handler的實(shí)例都關(guān)聯(lián)了一個(gè)線程和線程的消息隊(duì)列矫限。當(dāng)創(chuàng)建了一個(gè)Handler對(duì)象時(shí),一個(gè)線程或消息隊(duì)列同時(shí)也被創(chuàng)建佩抹,該Handler對(duì)象將發(fā)送和處理這些消息或Runnable對(duì)象叼风。)
2.Handler與線程相關(guān)的圖解
3.除了Handler引起的內(nèi)存泄漏,以下常見(jiàn)操作也會(huì)引起內(nèi)存泄漏:
3.1? IO操作沒(méi)有關(guān)流以及Cursor游標(biāo)的一些操作匹摇,忘記關(guān)掉Cusor咬扇;
3.2??Bitmap對(duì)象沒(méi)有recycle()釋放內(nèi)存;
3.3? 發(fā)送廣播廊勃、定義廣播接收者時(shí)沒(méi)有反注冊(cè)懈贺,以及EventBus的反注冊(cè);
3.4 接口回調(diào)時(shí)界面間持有引用坡垫,關(guān)閉不完全很可能引起的內(nèi)存泄漏梭灿;
比如,網(wǎng)絡(luò)請(qǐng)求使用Activity當(dāng)做回調(diào)冰悠,如果網(wǎng)速慢堡妒,設(shè)置了30秒才會(huì)鏈接超時(shí),此時(shí)按下返回鍵溉卓,Activity會(huì)被網(wǎng)絡(luò)請(qǐng)求給引用大約30秒然后才有可能被釋放皮迟。
3.5?單例模式導(dǎo)致內(nèi)存泄漏(實(shí)質(zhì)是靜態(tài)變量引用Activity),由于它的靜態(tài)特性使得其生命周期跟應(yīng)用一樣長(zhǎng)桑寨,如果我們把上下文Context(比如說(shuō)一個(gè)Activity)傳入到了單例類中的執(zhí)行業(yè)務(wù)邏輯伏尼,這時(shí)候靜態(tài)變量就引用了我們的Activity,如果沒(méi)有及時(shí)置空尉尾,就會(huì)在這個(gè)Activity?finish的時(shí)候爆阶,導(dǎo)致該Activty一直駐留在內(nèi)存中,并發(fā)生內(nèi)存泄漏沙咏,所以傳入上下文對(duì)象時(shí)應(yīng)Application的Context來(lái)替代和Activity相關(guān)的Context辨图;
3.6 bindService綁定服務(wù)后,沒(méi)有unbindService解綁服務(wù)肢藐,會(huì)導(dǎo)致ServiceConnection 泄露故河。