EditText вызвал утечку Activity. Текущий ответ на стекопоток не помог
У меня есть код с включенным Android Strict Mode, VmPolicy обнаруживает все и Penalty Death. Это включено в приложении.
Так что это помогает мне обнаружить утечку памяти. Мой код очень прост, 2 действия (почти пусто). У MainActivity есть кнопка, чтобы открыть SubActivity. SubActivity просто имеет один EditText.
Код можно получить здесь https://github.com/elye/issue_edittextleak
Если вы запустите код, из MainActivity перейдите в SubActivity и вернитесь в MainActivity (используя Back Key), а затем перейдите в SubActivity и вернитесь...
E/StrictMode: class com.elyeproj.edittextleak.SubActivity; instances=2; limit=1
android.os.StrictMode$InstanceCountViolation: class com.elyeproj.edittextleak.SubActivity; instances=2; limit=1
at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
Это потому, что обнаружена утечка SubActivity.
Почему SubActivity просочилась, потому что у него есть EditText. Удаление его приведет к тому, что он больше не будет течь.
Это происходит на Samsung S5 Lollipop 5.0 (v21). Это также протекает на KitKat (v19). Это не происходит на Samsung S7 Marshmallow и Nexus 6 (Nougat).
Это не происходит на Emulated Nexus 5 Lollipop 5.0.2 (v21). Но случается на v19 из Emulated Nexus 5.
Я проверил многие стековые потоки и не могу найти решение. Более подробную информацию об этой проблеме и моих исследованиях вы найдете в https://medium.com/@elye.project/hell-level-4-unleashed-by-android-strict-mode-dare-you-challenge-it-1dc9048bb4fb
Так чего я хочу? Я думаю, что утечка памяти была решена на Lollipop 5.0.2 и выше. Но для версии до этого, как я мог предотвратить утечку, в то время как я мог иметь editText?
2 ответа
Я думаю, что эта проблема не имеет ничего общего с редактированием текста, как из журнала строгого режима SubActivity; instances=2; limit=1
ясно, что у вас есть два экземпляра subActivity. Это происходит потому, что при каждом запуске subActivity вы создаете новый его экземпляр, эту проблему можно решить с помощью флагов режима запуска. singleInstance
или же singleTask
при запуске subActivity. которое гарантирует, что может существовать только один экземпляр активности.
РЕДАКТИРОВАТЬ 1:
Я поиграл с вашим кодом и обнаружил, что проблема воспроизводима в v19 версии Emulated Nexus 5. Я ясно, что эта проблема не имеет никакого отношения к редактированию текста, поскольку проблема воспроизводима, даже если у subActivity нет представлений, связанных с Это. Как ответили в этом сообщении о стека Oveflow, это может быть ошибка в строгом режиме, так как эта ссылка указывает
Если действие запускается, а затем выходит и перезапускается очень быстро, вы можете получить StrictMode.InstanceCountViolation.
Однако это просто потому, что сборщик мусора еще не завершил первый экземпляр Activity, то есть в памяти временно есть 2 (или более) экземпляра.
Вызов System.gc() перед startActivity() или startActivityForResult() остановит StrictMode.InstanceCountViolation
И с андроида DOcs
Не чувствуйте себя обязанным исправить все, что находит StrictMode. В частности, во многих случаях жизненного цикла часто требуется доступ к диску. Используйте StrictMode, чтобы найти вещи, которые вы сделали случайно. Однако сетевые запросы в потоке пользовательского интерфейса почти всегда являются проблемой.
Используйте этот код для завершения SubActivity .
Добавьте этот код в файл класса SubActivity .
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}