活动中的匿名回调
每次创建匿名类时,它都会保留对其父类的隐式引用。所以当你写:
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);
}
}