Android上 ,Context可以用于很多操作,但是大部份時(shí)候是用來(lái)加載和使用資源。這就是為何所有的widgets在他們的構(gòu)造函數(shù)中接受1個(gè)Context參數(shù)。在1般的android利用中,你通常有兩種Context:分別是Activity和Application。通常的,當(dāng)我們的類(lèi)和方法需要使用到context時(shí),我們傳遞的是Activity這個(gè)context。
這個(gè)例子展現(xiàn)了1個(gè)最簡(jiǎn)單的Context
泄漏的情況,你可以在Home screen 的源碼中看到我們是如何解決這個(gè)問(wèn)題的( 查找unbindDrawables() 方法) ,這就是當(dāng)activity 被燒毀的時(shí)候?qū)rawables 的回調(diào)設(shè)為null 。有趣的是,你可能創(chuàng)造出1系列context泄漏的情況有很多,這非常糟。他們會(huì)是你很快內(nèi)存溢出。
有兩種簡(jiǎn)單的方法來(lái)避免context 相干的內(nèi)存泄漏。最顯著地1個(gè)是避免context 逃出他自己的范圍以外。上面的例子就展現(xiàn)了使用靜態(tài)援用的情況,而內(nèi)部類(lèi)和他們對(duì)外部類(lèi)的的隱式援用也是一樣危險(xiǎn)的。第2種方法是使用Application context 。這個(gè)context 的生存周期和你的利用的生存周期1樣長(zhǎng),而不是取決于activity 的生存周期。如果你想保持1個(gè)長(zhǎng)時(shí)間生存的對(duì)象,并且這個(gè)對(duì)象需要1個(gè)context ,記得使用application 對(duì)象。你可以通過(guò)調(diào)用Context.getApplicationContext()
or Activity.getApplication() 來(lái)取得。
總而言之,想要避免context 相干的內(nèi)存泄漏 ,記住以下幾點(diǎn):
1、不要對(duì)activity 的context 長(zhǎng)時(shí)間援用( 1個(gè)activity 的援用的生存周期應(yīng)當(dāng)和activity 的生命周期相同)
2、試著使用關(guān)于application的 context 來(lái)替換和activity相干的context
3、如果1個(gè)acitivity 的非靜態(tài)內(nèi)部類(lèi)的生命周期不受控制,那末避免使用它;使用1個(gè)靜態(tài)的內(nèi)部類(lèi)并且對(duì) 其中的activity 使用1個(gè)弱援用。解決這個(gè)問(wèn)題的方法是使用1個(gè)靜態(tài)的內(nèi)部類(lèi),并且對(duì)它的外部類(lèi)有1 WeakReference,就像在ViewRoot中內(nèi)部類(lèi)W所做的就是這么個(gè)例子。
4、垃圾回收器不能處理內(nèi)存泄漏的保障