翻譯自:http://android-developers.blogspot.sg/2009/01/avoiding-memory-leaks.html
Android中堆的內(nèi)存是有限的贮缅,你應當使用盡量小的內(nèi)存介却。因為Android能在內(nèi)存中保存越多的應用,對于用戶來說桂肌,切換應用就會十分的迅速胃夏。相當多的內(nèi)存泄漏的原因是因為:保持了一個對context的長引用(long-lived)。
在Android中仰禀,Context可以用來做許多事情答恶,不過大部分是用來加載和獲取資源萍诱。這就是為什么所有的視圖組件在構造方法里面需要context作為參數(shù)的原因。有兩種Context裕坊,Activity和Application,通常使用第一個周瞎。比如:
TextView label =new TextView(this);
這代表著views持有一個對于activity的引用饵蒂。所以,如果你泄漏了Context(你保留了一個對它的引用退盯,在GC的時候保護了它)。如果你不夠小心的話慰照,泄漏掉整個Activity是很容易的琉朽。
當屏幕的顯示方向發(fā)生變化時,系統(tǒng)將會(默認)銷毀現(xiàn)在的Activity漓骚,維護它的一些數(shù)據(jù)然后新建一個Activity榛泛。如果這樣做的話曹锨,Android 將會重新讀取UI剃允。想象一下,你在你的應用里面使用了一個大bitmap斥废,你不想每次旋轉的時候都重新加載它。最簡單的方法就是把它放在一個靜態(tài)域里面捧灰。
private static Drawable sBackground;
@Override
Protected void onCreate(Bundle state){
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
if(sBackground == null){
sBackground = getDrawable(R.drawable.shoothzj);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
上述代碼很快但是是錯誤的统锤,它泄漏了在第一次屏幕旋轉之前的Activity。當一個Drawable連系在view上時煌寇,view就像被設置為drawable的回調一樣逾雄。對于上面的代碼,就是說drawable持有了對于textview的引用鸦泳,而textview又持有了activity的引用。這就把Activity泄漏掉了徒仓。當Activity被銷毀的時候,把drawable的回調設置為null掉弛。
有兩種簡單的方式去避免內(nèi)存泄漏喂走。第一個就是避免context超范圍的使用。例子上展示的是靜態(tài)引用但是內(nèi)部類以及他們持有的對外部類的明確引用也同樣危險乎芳。第二個解決方法,利用Application context奈惑,這個context的存活時間跟你的應用一樣久。如果打算保持一個長久的對象寂殉,就用 Context.getApplicationContext() 或者 Activity.getApplication()原在。