Отслеживание View добавлено в WindowManager (нет функции findViewById()?)

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

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

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

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

Ответы

Ответ 1

В моей службе я добавляю представление WindowManager с помощью addView(). Когда я готов скрыть представление, я вызываю removeView() с помощью ссылки View. Это отлично работает - большую часть времени. У меня есть случайные отчеты Force Close, которые говорят, что 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) {}

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

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

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

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

Ответ 2

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

Ответ 3

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

if(mView.getParent() != null){
   wm.removeView(mView);
}

Ответ 4

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

ViewCompat.isAttachedToWindow(mView);

Согласно документам:

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