#android #android-context #nsd #nsdmanager
#Android #android-контекст #nsd #nsdmanager
Вопрос:
При профилировании моего приложения я обнаружил, что извлечение NsdManager с помощью
nsdManager = (NsdManager) getSystemService(Context.NSD_SERVICE); // LEAKS!
происходит утечка активности, в то время как
nsdManager = (NsdManager) getApplicationContext().getSystemService(Context.NSD_SERVICE);
нет. Я создал небольшое тестовое приложение, которое ничего не делает с
NsdManager, кроме как извлекает его с помощью контекста Activity,
но оно все еще пропускает activity. Это ошибка? Действительно
ли мне нужно постоянно использовать контекст приложения?
Устройство: Эмулятор (Android 11, API 30, x86)
Комментарии:
1. Как вы определяете, что происходит утечка? Что это утечка? Вы видите утечку в более старых версиях Android?
2. GitHub: github.com/roplacebo/NsdManager.git . Нажмите кнопку, чтобы перейти к NsdActivity, где NsdManager извлекается из контекста действия. Затем вернитесь назад. Дампы кучи с утечкой Canary и профилировщиком памяти. То же самое с Samsung Galaxy Tab S2 (Nougat)
3. Хорошо, я могу воспроизвести проблему с вашим проектом. Я не уверен, насколько «реальна» утечка. Что-то глубоко в внутренностях Android содержит
AsyncChannel
ссылку на вашу активность, и я не знаю, будет ли / когда эта ссылка будет выпущена. Вы можете подумать о том, чтобы следовать инструкциям этой записи часто задаваемых вопросов, чтобы попытаться определить, относится ли это к LeakCanary как «утечка библиотеки» или нет.4. Спасибо, что изучили это! Я подал ошибку здесь: issuetracker.google.com/issues/173689855
Ответ №1:
Эта проблема похожа на проблемы с утечкой памяти при получении WIFI_SERVICE.
При выполнении:
activity.getSystemService(Context.WIFI_SERVICE);
Android Studio lint показывает следующее предупреждение.
The WIFI_SERVICE must be looked up on the
Application context or memory will leak on
devices < Android N. Try changing activity
to activity.getApplicationContext().
Хотя в NSD_SERVICE нет предупреждения об утечке и потому, что я вижу утечки памяти, ссылающиеся на NsdManager при использовании:
activity.getSystemService(Context.NSD_SERVICE);
Я думаю, что с помощью:
activity.getApplicationContext().getSystemService(Context.NSD_SERVICE);
похоже, правильное действие.