活動中的匿名回撥

每次建立匿名類時,它都會保留對其父類的隱式引用。所以當你寫:

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