InputMethodManager содержит ссылку на tabhost - Memory Leak - OOM Error
Иерархия просмотра выглядит следующим образом TabActivity
→ ActivityGroups
→ Activities
.
Используя MAT, я обнаружил, что TabWidget
ссылается на TabHost
, на который ссылается InputMethodManager
, поэтому TabWidget
просочился. On Последующий запуск приложения OutOfMemory Ошибка.
Аналогично, все мои действия также ссылаются на InputMethodManager
.
(После закрытия приложения все мои группы активности, действия, tabactivity, tabhost и tabwidget просачиваются!!)
При правильной обработке приложения (нажатие клавиши возврата) в логарифме
показано следующее:
WARN/InputManagerService (99): запуск ввода для неконцентрированного клиента. [email protected] (uid = 10052 pid = 1463)
Как удалить ссылку из InputMethodManager
...?
Вещь, которую я пробовал:
а. Вызывается этот метод onDestroy
моего TabActivity
1. myTabWidget.removeAllViews()
2. myTabWidger.invalidate()
Нет удачи!
Ответы
Ответ 1
Вещь, которую я пробовал: A. Называется этот метод onDestroy моей TabActivity 1.myTabWidget.removeAllViews() 2.myTabWidger.invalidate()
Конечно, это не сработает. Действия не являются представлениями ни в MVC/MVP/MVVM, ни в иерархии классов Android SDK. android.app.Activity не поддерживает android.view.View
У моего коллеги была аналогичная проблема с утечками памяти - он объявлял tabHost в TabActivity статическим способом (он хотел получить к нему доступ из другого действия, когда он не был знаком с шаблоном Observer). Я думаю, вы сделали что-то подобное.
И, наконец, мой вопрос: почему вы ссылаетесь на действия в InputMethodManager (хотя я не понимаю, как это: final class), а не InputMethodManager в действиях? Если вам нужна глобальная точка фокусировки для InputMethodManager, я могу посоветовать вам поместить ее в класс Application. Мы расширяем класс Application (например, HostApplication), на этом фасаде мы объявляем общий материал (например, SharedPreferences). И в действиях мы пишем:
HostApplication application = (HostApplication) getApplication();
Затем мы получаем полезный общий материал из него.
Ответ 2
Я также встретил эту проблему, и я попытался каким-то образом избежать этого. Когда моя активность закончена, я пытаюсь отключить соединение с помощью службы диспетчера методов ввода. Проверьте это:
class MyActivity extend Activity {
@Override
public void finish() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.windowDismissed(mContentView.getWindowToken());
super.finish();
}
}
Я не уверен, может ли это исправить утечку памяти вообще. На данный момент он работает нормально. Вы можете попробовать.
Ответ 3
Вы уверены, что утечка памяти реальна? У меня подобная ситуация, и, хотя она похожа на утечку памяти в MAT, я не могу получить два экземпляра TabActivity для отображения из-за InputMethodManager. Конечно, InputMethodManager, похоже, сохраняет TabActivity от сбора мусора. Но если это была настоящая утечка памяти, разве я не смогу увидеть две TabActivites, затем три, затем четыре?
(FYI, я смог увидеть две TabActivities в какой-то момент, но проблема была не в InputMethodManager, это была статическая ссылка в коде)