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();
    }
Другие вопросы по тегам