每次创建匿名类时,它都会保留对其父类的隐式引用。所以当你写:
public class LeakyActivity extends Activity { ... foo.registerCallback(new BarCallback() { @Override public void onBar() { // 做点什么 } }); }
实际上,您是将对LeakyActivity实例的引用发送给foo。当用户离开您的LeakyActivity导航时,此引用可以防止LeakyActivity实例被垃圾回收。这是一个严重的泄漏,因为活动拥有对其整个视图层次结构的引用,因此是内存中的相当大的对象。
如何避免这种泄漏:
您当然可以避免在活动中完全使用匿名回调。您还可以注销有关活动生命周期的所有回调。像这样:
public class NonLeakyActivity extends Activity { private final BarCallback mBarCallback = new BarCallback() { @Override public void onBar() { // 做点什么 } }); @Override protected void onResume() { super.onResume(); foo.registerCallback(mBarCallback); } @Override protected void onPause() { super.onPause(); foo.unregisterCallback(mBarCallback); } }