活動中的匿名回撥
每次建立匿名類時,它都會保留對其父類的隱式引用。所以當你寫:
public class LeakyActivity extends Activity
{
...
foo.registerCallback(new BarCallback()
{
@Override
public void onBar()
{
// do something
}
});
}
你實際上是將你的 LeakyActivity 例項的引用傳送到 foo。當使用者導航離開 LeakyActivity 時,此引用可以防止 LeakyActivity 例項被垃圾回收。這是一個嚴重的洩漏,因為活動持有對其整個檢視層次結構的引用,因此在記憶體中是相當大的物件。
如何避免這種洩漏:
你當然可以完全避免在活動中使用匿名回撥。你還可以取消註冊與活動生命週期相關的所有回撥。像這樣:
public class NonLeakyActivity extends Activity
{
private final BarCallback mBarCallback = new BarCallback()
{
@Override
public void onBar()
{
// do something
}
});
@Override
protected void onResume()
{
super.onResume();
foo.registerCallback(mBarCallback);
}
@Override
protected void onPause()
{
super.onPause();
foo.unregisterCallback(mBarCallback);
}
}