Невозможно добавить окно - токен android.os.BinderProxy недействителен; ваша деятельность идет?

116

Я пытаюсь подключиться к Facebook через API Facebook, следую этому примеру: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

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

public void onAuthSucceed() {
        mText.setText("You have logged in! ");   
        //This is the code to call the post message dialog.                     
        mFacebook.dialog(Example.this, "feed",new SampleDialogListener());   
    }

Я получаю эту ошибку в журнале регистрации:

03-02 13:32:08.629: E/AndroidRuntime(14991): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@405180f8 is not valid; is your activity running?
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.ViewRoot.setView(ViewRoot.java:532)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.view.Window$LocalWindowManager.addView(Window.java:424)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.app.Dialog.show(Dialog.java:241)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Facebook.dialog(Facebook.java:780)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Facebook.dialog(Facebook.java:737)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Example$SampleAuthListener.onAuthSucceed(Example.java:113)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.SessionEvents.onLoginSuccess(SessionEvents.java:78)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Example$LoginDialogListener.onComplete(Example.java:88)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.Facebook$1.onComplete(Facebook.java:320)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.android.FbDialog$FbWebViewClient.shouldOverrideUrlLoading(FbDialog.java:144)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:218)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:337)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.os.Looper.loop(Looper.java:130)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at android.app.ActivityThread.main(ActivityThread.java:3687)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at java.lang.reflect.Method.invokeNative(Native Method)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at java.lang.reflect.Method.invoke(Method.java:507)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at dalvik.system.NativeStart.main(Native Method)

Любая идея?

Хан Тран
источник
1
Проверьте ответ ниже. Я отметил, что это правильно :)
Хан Тран
Тот факт, что вы отметили ответ, не меняет того факта, что это повторяющийся вопрос. Другой вопрос был задан первым и представляет собой идентичный вопрос с практически идентичным ответом.
bsara
1
Вы видели, что у меня вопрос 2 года назад?
Хан Тран
1
Так что, похоже, у других Модератор ошибка, а у тебя :)) Анв, спасибо!
Хан Тран

Ответы:

127

Это может произойти, когда вы показываете диалог для контекста, который больше не существует. Распространенный случай - если операция «показать диалог» выполняется после асинхронной операции, и во время этой операции исходное действие (которое должно быть родительским для вашего диалога) уничтожается. Хорошее описание см. В этом сообщении в блоге и в комментариях:

http://dimitar.me/android-displaying-dialogs-from-background-threads/

Из трассировки стека выше видно, что библиотека facebook запускает операцию аутентификации асинхронно, и у вас есть механизм Handler - Callback (onComplete, вызываемый на слушателе), который может легко создать этот сценарий.

Когда я видел это в своем приложении, это довольно редко и соответствует опыту в сообщении в блоге. Что-то пошло не так с действием / оно было уничтожено во время работы AsyncTask. Я не знаю, как ваша модификация может приводить к этому каждый раз, но, возможно, вы ссылаетесь на Activity как на контекст для диалога, который всегда уничтожается во время выполнения вашего кода?

Кроме того, хотя я не уверен, что это лучший способ узнать, выполняется ли ваша деятельность, см. Этот ответ, чтобы узнать об одном из способов сделать это:

Проверить, активна ли активность

Питер Паскаль
источник
3
Отсутствие вызова dialog.show()решает проблему, но что нужно сделать, чтобы по-прежнему отображать мой диалог?
нацумию
Для меня я звоню Fragment.getContext(), что работает для API выше 21. Но на Lollipop он вылетает
TheRealChx101 02
158

Время от времени я получал сообщения об этой ошибке из некоторых моих приложений, и вот что решило ее для меня:

if(!((Activity) context).isFinishing())
{
    //show dialog
}

Все остальные ответы, похоже, делают странные вещи, такие как итерация по списку выполняемых действий, но это намного проще и, похоже, помогает.

DiscDev
источник
6
это не решает проблему, это предотвращает сбой и также показывает диалог
YTerle
6
Просто помните, что вы должны проверить, context instanceof Activityиначе вы можете получить Exception!
FtheBuilder
3
или вы можете использовать getActivity (). isFinishing () вместо контекста
Никита Аксёнов
Я использую API-23. Когда я пытаюсь использовать это в своей MainActivity, которая расширяет AppCompatActivity. Он показывает мне ошибку типа Caused by: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController не может быть преобразован в android.app.Activity в com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppController - это добавлен в мой AndroidMenifest
Павел
Я не использую никаких диалогов и получаю эту ошибку.
Абдул Вахид
11

один простой обходной путь - поймать исключение:

try {
        alertDialog.show()
    }
catch (WindowManager.BadTokenException e) {
        //use a log message
    }

Это не изящно, но иногда просто, когда вам нужно управлять асинхронными операциями, и вы не уверены, активна ли активность, когда вы хотите показать диалог.

Герц
источник
1
такая уродливая, но такая красивая!
Рахул Тивари,
8
  • В моем случае проблема возникла из-за того, что я пытаюсь открыть / показать диалоговое окно в onPostExecuteAsyncTask.

  • Однако это неправильный метод showing dialogили изменение пользовательского интерфейса onPostExecute.

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

    @Override
    protected void onPostExecute(String response_str) {
    
       getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!((Activity) mContext).isFinishing()) {
                            try {
                                ShowAgilDialog();
                            } catch (WindowManager.BadTokenException e) {
                                Log.e("WindowManagerBad ", e.toString());
                            }
                        }
                    }
                });
    }
Agilanbu
источник
1

Я столкнулся с той же проблемой. Вызов '(!isFinishing())'предотвратил сбой, но не смог отобразить «предупреждение».

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

Например:

public static void connect_failure() {      
        Log.i(FW_UPD_APP, "Connect failed");

        new AlertDialog.Builder(MyActivity)
        .setTitle("Title")
        .setMessage("Message")
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) { 
                  //do nothing
            }
         })
        .setIcon(R.drawable.the_image).show();      
    }
ArunJTS
источник
1

После выполнения потока добавьте эти две строки кода, и это решит проблему.

Looper.loop();
Looper.myLooper().quit();
Балачандран Мутурадж
источник
1

Другое использование разработчик случай: Если WindowManagerили getWindow()вызываются на onCreate()или onStart()или onResume(), BadTokenExceptionотбрасываются. Вам нужно будет подождать, пока вид будет подготовлен и прикреплен.

Перемещение кода для onAttachedToWindow()ее решения. Возможно, это не постоянное решение, но, насколько я мог проверить, оно всегда работало.

В моем случае требовалось увеличить яркость экрана, когда активность стала видна. Строка getWindow().getAttributes().screenBrightnessв onResume()списке привела к исключению. Перемещение кода в onAttachedToWindow()рабочий.

Рам Айер
источник
0

Для меня это было исправлено путем простого удаления staticсвойства в методах DialogHelper.class (предназначенных для создания и скрытия диалога), поскольку у меня есть свойства, связанные с Windowэтими методами

Дассер Басюни
источник
0

В dependencyServices мне ничего из вышеперечисленного не помогло, в итоге я сделал, как показано ниже:

    class Static_Toast_Android
    {
        private static Context _context
        {
            get { return Android.App.Application.Context; }
        }
        public static void StaticDisplayToast(string message)
        {
            Toast.MakeText(_context, message, ToastLength.Long).Show();
        }
    }
    public class Toast_Android : IToast
    {

        public void DisplayToast(string message)
        {
            Static_Toast_Android.StaticDisplayToast(message);
        }
    }

Я должен использовать «двойной класс», потому что интерфейс не может быть статичным. L-

Легион
источник
0

Невозможно добавить окно - токен недействителен; ваша деятельность идет?

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

Внешние ресурсы

Android - отображение диалогов из фоновых потоков

Ошибка: BinderProxy @ 45d459c0 недействителен; ваша деятельность идет?

Болендра Сингх
источник
0

Я решил это, поставив это:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}
Хуан Л. Антон Сантамария
источник
Пожалуйста, выбирайте английский язык при публикации
Педро Коэльо