活动中的匿名回调

每次创建匿名类时,它都会保留对其父类的隐式引用。所以当你写:

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);
    }
}