android view windowmanager badtokenexception

Из моего основного activity мне нужно вызвать внутренний класс, а в методе внутри класса мне нужно показать AlertDialog . После его закрытия, когда нажата кнопка ОК, переходим в Google Play для покупки.

В большинстве случаев все работает идеально, но для немногих пользователей происходит сбой на builder.show() , и я вижу «android.view.WindowManager$BadTokenException: Невозможно добавить окно «из журнала сбоев. Пожалуйста, предложите.

Мой код очень похож на это:

Я также видел ошибку в другом предупреждении, когда я не пересылаю ни в какой другой activity . Это просто так:

Проблема:

Это исключение возникает, когда приложение пытается уведомить пользователя из фоновый поток (AsyncTask), открыв диалоговое окно.

Если вы пытаетесь изменить пользовательский интерфейс из фонового потока (обычно из onPostExecute() AsyncTask), и если действие входит в завершающий этап i.e.), явно вызывающий финиш(), нажатие на пользователя или кнопку «Назад» или очистка активности, сделанные Android, тогда вы получите это ошибка.

Причина:

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

Решение:

Использовать метод isFinishing() , который вызывается Android для проверки того, эта деятельность находится в процессе отделки: будь то явная обработка() звонка или активности, сделанных Android. Используя этот метод, очень легко избежать открытия диалога из фонового потока, когда активность заканчивается.

Также поддерживайте weak reference для активности (и не сильный ссылку, чтобы активность могла быть уничтожена, когда это не было необходимо) и проверьте если активность не заканчивается, прежде чем выполнять какой-либо пользовательский интерфейс, используя этот (т.е. показывая диалог).

например,.

Обновление:

Токены окна:

Как следует из его названия, токен окна — это особый тип токена Binder что диспетчер окон использует уникальную идентификацию окна в система. Ярлыки окна важны для безопасности, потому что они делают это невозможно, чтобы вредоносные приложения рисовали поверх окон других приложений. Менеджер окон защищает это от требуя, чтобы приложения передавали свой токен окна приложения как часть каждого запроса для добавления или удаления окна. Если токены не match, оконный менеджер отклоняет запрос и бросает BadTokenException. Без оконных жетонов это необходимо шаг идентификации был бы невозможным, а диспетчер окон не сможет защитить себя от вредоносных приложений.

Реальный сценарий:

Когда приложение запускается в первый раз, ActivityManagerService создает специальный вид токена окна называемый токеном окна приложения, который однозначно идентифицирует окно верхнего уровня приложения. Менеджер активности дает этот токен как для приложения, так и для диспетчера окон, и приложение посылает маркер в оконный менеджер каждый раз, когда он хочет для добавления нового окна на экран. Это обеспечивает безопасное взаимодействие между приложением и менеджером окон (путем создания невозможно добавить окна поверх других приложений), а также упрощает диспетчеру активности прямые запросы к оконный менеджер.

Из моего основного действия мне нужно вызвать внутренний класс и метод внутри класса, мне нужно показать AlertDialg и отпустить его, когда кнопка OK нажата и переадресовывается в Google Play для покупки.

Вещи отлично работают в большинстве случаев, но для нескольких пользователей он падает на builder.show() , и я вижу «android.view.WindowManager$BadTokenException: Невозможно добавить окно «из журнала сбоев». Пожалуйста, предложите.

Мой код примерно так:

Я также видел ошибку в другом предупреждении, где я не пересылаю никакую другую активность. Это просто:

7 ответов

Это исключение возникает, когда приложение пытается уведомить пользователя из фонового потока (AsyncTask), открыв диалоговое окно.

Если вы пытаетесь изменить пользовательский интерфейс из фонового потока (обычно из onPostExecute () AsyncTask), и если действие переходит к завершающему этапу, то есть прямому вызову finish (), пользователь нажимает кнопку «домой» или «назад» или активность

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

Использовать метод isFinishing() , который вызывается Android чтобы проверить, находится ли эта деятельность в процессе отделки: будь то явный финиш () вызов или очистка активности, сделанная Android. Используя этот метод, очень легко избежать открытия диалога из фонового потока при завершении операции.

Также поддерживать weak reference для активности (а не сильную ссылку, чтобы активность можно было уничтожить, )

Обновление: если вы не выполняете какой-либо пользовательский интерфейс, используйте эту ссылку (например,

Как следует из его названия, токен окна является специальным типом маркера Binder, который оконный менеджер использует для уникальной идентификации окна в системе. Ярлыки окна важны для безопасности, потому что они делают невозможным использование вредоносных приложений поверх окон других приложений. Менеджер окон защищает от этого, требуя от приложений передать токен своего приложения как часть каждого запроса на добавление или удаление окна. Если жетоны не совпадают, диспетчер окон отклоняет запрос и генерирует исключение BadTokenException. Без токенов окна этот необходимый шаг идентификации не был бы возможен, и оконный менеджер не смог бы защитить себя от вредоносных приложений.

Когда приложение запускается в первый раз, ActivityManagerService создает специальный вид токена окна, называемый токеном окна приложения, который однозначно идентифицирует окно контейнера верхнего уровня приложения. Диспетчер активности предоставляет этот токен как для приложения, так и для диспетчера окон, и приложение отправляет токен в оконный менеджер каждый раз, когда хочет добавить на экран новое окно. Это обеспечивает безопасное взаимодействие между приложением и диспетчером окон (делая невозможным добавление окон поверх других приложений), а также упрощает диспетчеру активности непосредственные запросы к диспетчеру окон.

From my main activity , I need to call an inner class and in a method within the class, I need to show AlertDialog . After dismissing it, when the OK button is pressed, forward to Google Play for purchase.

Things work perfectly for most of the times, but for few users it is crashing on builder.show() and I can see «android.view.WindowManager$BadTokenException: Unable to add window» from crash log. Please suggest.

My code is pretty much like this:

I have also seen the error in another alert where I am not forwarding to any other activity . It’s simple like this:

8 Answers 8

Problem :

This exception occurs when the app is trying to notify the user from the background thread (AsyncTask) by opening a Dialog.

If you are trying to modify the UI from background thread (usually from onPostExecute() of AsyncTask) and if the activity enters finishing stage i.e.) explicitly calling finish(), user pressing home or back button or activity clean up made by Android then you get this error.

Reason :

The reason for this exception is that, as the exception message says, the activity has finished but you are trying to display a dialog with a context of the finished activity. Since there is no window for the dialog to display the android runtime throws this exception.

Solution:

Use isFinishing() method which is called by Android to check whether this activity is in the process of finishing: be it explicit finish() call or activity clean up made by Android. By using this method it is very easy to avoid opening dialog from background thread when activity is finishing.

Also maintain a weak reference for the activity (and not a strong reference so that activity can be destroyed once not needed) and check if the activity is not finishing before performing any UI using this activity reference (i.e. showing a dialog).

eg.

Update :

Window Tokens:

As its name implies, a window token is a special type of Binder token that the window manager uses to uniquely identify a window in the system. Window tokens are important for security because they make it impossible for malicious applications to draw on top of the windows of other applications. The window manager protects against this by requiring applications to pass their application’s window token as part of each request to add or remove a window. If the tokens don’t match, the window manager rejects the request and throws a BadTokenException. Without window tokens, this necessary identification step wouldn’t be possible and the window manager wouldn’t be able to protect itself from malicious applications.

A real-world scenario:

When an application starts up for the first time, the ActivityManagerService creates a special kind of window token called an application window token, which uniquely identifies the application’s top-level container window. The activity manager gives this token to both the application and the window manager, and the application sends the token to the window manager each time it wants to add a new window to the screen. This ensures secure interaction between the application and the window manager (by making it impossible to add windows on top of other applications), and also makes it easy for the activity manager to make direct requests to the window manager.

Оцените статью