Ответ 1
Если вы вращаете устройство, тот же класс MyActivity
(или другое имя, которое вы ему дали) воссоздается, обратный вызов перезаписывается и утечка существует до следующего GC. Проблема заключается в том, что вы переходите к другому действию, сохраняя ссылку на старый. Сегодня это смягчается, потому что setCallback
теперь сохраняет обратный вызов в WeakReference
, как вы можете видеть в текущем графическом коде, но это была сильная ссылка один раз (найдите setCallback(Callback cb)
). В любом случае, вы правы, если вы просто посмотрите на одно действие, обратный вызов будет reset после поворота.
(редактировать, абзац добавлен):
Например: MainAcivity @1 - это первый экземпляр. Когда вы вращаетесь, он уничтожается и создается новый MainActivity @2. Сначала происходит утечка, но как только sDrawable
переназначается, MainActivity @1 можно бесплатно собрать, и проблем нет. Теперь предположим, что вместо поворота вы переходите к SecondActivity. Теперь sDrawable
предназначен только для MainActivity
и по-прежнему содержит ссылку на MainActivity @2, поэтому он протекает.
Смотрите этот код:
package com.douglasdrumond.leaky;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.widget.TextView;
public class MainActivity extends Activity {
private static Drawable sBackground;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView label = new TextView(this);
System.gc();
long memory = Runtime.getRuntime().totalMemory()
- Runtime.getRuntime().freeMemory();
label.setText("Memory: " + memory / 1024f);
if (sBackground == null) {
sBackground = getResources().getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
}
Очевидно, что вращение не увеличивает использование памяти.