Почему предупреждение об утечке для обработчика1?
По причине предупреждения об утечке эта статья объясняет очень хорошо.
Цитата из статьи
В Java нестатические внутренние и анонимные классы содержат неявную ссылку на свой внешний класс.Статические внутренние классы, с другой стороны, этого не делают.
Поэтому, когда вы создали handler1
анонимным классом, он будет содержать ссылку на экземпляр MainActivity
, и MainActiviy
не может бытьсборщик мусора.
Решение
Повторное цитирование статьи
Чтобы устранить проблему, создайте подкласс Handler в новом файле или используйте статический внутреннийкласс вместо .Статические внутренние классы не содержат неявной ссылки на свой внешний класс, поэтому активность не будет пропущена.Если вам нужно вызывать методы внешнего действия из обработчика, пусть обработчик удерживает WeakReference для действия, чтобы вы случайно не пропустили контекст.Чтобы устранить утечку памяти, возникающую при создании экземпляра анонимного класса Runnable, мы делаем переменную статическим полем класса (поскольку статические экземпляры анонимных классов не содержат неявной ссылки на их внешний класс):
Следуя статье, обновите свой код следующим образом:
public class MainActivity extends AppCompatActivity {
private static class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("LOG", "Hello~1");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler handler1 = new MyHandler();
handler1.postDelayed(new Runnable() {
@Override
public void run() { }
}, 60000);
finish();
}
}
Может ли handler2 решить проблему?
Ответ от @Michael Этот класс Handler должен быть статическим или иметь утечкиможет произойти: IncomingHandler предоставляет решение.
Цитата из ответа @Michael
Насколько я понимаю, это не избежит потенциальной утечки памяти.Объекты сообщения содержат ссылку на объект mIncomingHandler, который содержит ссылку на объект Handler.Callback, который содержит ссылку на объект Service.Пока в очереди сообщений Looper есть сообщения, Служба не будет GC.Однако это не будет серьезной проблемой, если у вас нет сообщений с длительной задержкой в очереди сообщений.
В вашем случае handler2
будет содержать ссылку на Handler.Callback
object.And начиная с Handler.Callback
создается анонимным классом, следовательно, он также будет содержать ссылку на экземпляр MainActiviy
.Так что MainActiviy
экземпляр также не может быть собран мусором.