Отслеживание View добавлено в WindowManager (без функции findViewById ()?) - PullRequest
17 голосов
/ 29 июня 2011

В моем сервисе я добавляю представление к WindowManager с addView().Когда я готов скрыть вид, я звоню removeView(), используя ссылку View.Это прекрасно работает - большую часть времени.

У меня есть случайные отчеты Force Close, в которых говорится, что представление не привязано к WindowManager.Это имеет смысл.Проблема в том, что я думаю, что сервис убивается из-за Android, и когда приходит время скрыть представление, он пытается удалить неправильный View.

Я попытался проверить, чтобы представление былоnull, но, видимо, это не так, просто это не тот, который прикреплен к WindowManager.Похоже, что если ссылка на просмотр утеряна, то нет никакого способа снова получить к ней доступ.

Как получить эквивалент findViewById() на самом WindowManager?View автоматически удаляется из WindowManager, если моя служба остановлена ​​(убита)?Есть ли способ сохранить ссылку на View, чтобы, если служба остановлена, я мог удалить View позже (я также пытаюсь избежать утечки View)?

Ответы [ 4 ]

11 голосов
/ 23 июля 2011

В моем сервисе я добавляю представление в WindowManager с помощью addView ().Когда я готов скрыть представление, я вызываю removeView (), используя ссылку View.Это прекрасно работает - большую часть времени.Я иногда получаю отчеты о принудительном закрытии, в которых говорится, что представление не присоединено к WindowManager.

У меня точно такая же проблема.Надеемся, что эксперт примет участие.

Как я могу получить эквивалент findViewById () для самого WindowManager?

Сохраните ссылку на добавленное представление ипросто используйте removeView (mView).

В настоящее время в моей службе добавьте представление:

WindowManager.LayoutParams params = ...
mView = new View(this);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);

Затем, чтобы удалить представление, я избегаю случайного FC, перехватывая исключение:

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
try {
    wm.removeView(mView);
} catch (Exception e) {}

Является ли представление автоматически удаляемым из WindowManager, если моя служба остановлена ​​(убита)?

По моему опыту, они удаляются при остановке службы.Вы можете проверить это, остановив свой сервис, не удаляя представления.Не знаю, почему это работает, хотя.

Меня беспокоит то, что моя вторая ссылка на WM отличается, когда я иду, чтобы удалить представление.Если это так, то отображается ли mView, когда я ловлю исключение?Я попытался бы сохранить ссылку на WM, когда добавляю представление, но у меня были проблемы, когда ссылки на системные службы со временем кажутся плохими.

Дайте мне знать, если вы когда-нибудь решали эту проблему.

5 голосов
/ 22 апреля 2015

Чтобы проверить, было ли представление успешно присоединено к диспетчеру Windows или все еще подключено, вы можете использовать view.isShown();.

2 голосов
/ 15 декабря 2016

Вы также можете использовать:

ViewCompat.isAttachedToWindow(mView);

По документам:

Возвращает true, если предоставленный вид в настоящее время прикреплен к окну.

2 голосов
/ 04 мая 2016

Убедитесь, что родительские представления! = Null, прежде чем пытаться удалить его.

if(mView.getParent() != null){
   wm.removeView(mView);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...