InputMethodManager содержит ссылку на tabhost - Memory Leak - OOM Error

Иерархия просмотра выглядит следующим образом TabActivityActivityGroupsActivities.

Используя 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, это была статическая ссылка в коде)