No se puede agregar la ventana: el token android.os.BinderProxy no es válido; ¿Tu actividad se está ejecutando?

116

Intento conectarme a Facebook a través de la API de Facebook, sigo este ejemplo: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

Todo está bien, pero cuando trato de editar algún código, quiero decir que quiero mostrar el mensaje de diálogo después de que el inicio de sesión sea exitoso así:

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());   
    }

Recibo este error en el logcat:

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)

¿Alguna idea?

Han Tran
fuente
1
Compruebe la respuesta a continuación. He marcado que es correcto :)
Han Tran
El hecho de que haya marcado la respuesta no cambia el hecho de que esta es una pregunta duplicada. El otro se preguntó primero y es un problema idéntico con una respuesta esencialmente idéntica.
bsara
1
¿Viste que mi pregunta es de hace 2 años?
Han Tran
1
Así que parece que otros moderadores se han equivocado, pero tú :)) ¡Anw, gracias!
Han Tran

Respuestas:

127

Esto puede ocurrir cuando muestra el cuadro de diálogo para un contexto que ya no existe. Un caso común: si la operación 'mostrar diálogo' es después de una operación asincrónica, y durante esa operación se destruye la actividad original (es decir, el padre de su diálogo). Para una buena descripción, vea esta publicación de blog y comentarios:

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

A partir del seguimiento de la pila anterior, parece que la biblioteca de Facebook genera la operación de autenticación de forma asincrónica, y tiene un mecanismo Handler - Callback (llamado onComplete a un oyente) que podría crear fácilmente este escenario.

Cuando he visto este informe en mi aplicación, es bastante raro y coincide con la experiencia en la publicación del blog. Algo salió mal para la actividad / se destruyó durante el trabajo de AsyncTask. No sé cómo su modificación podría resultar en esto cada vez, pero tal vez esté haciendo referencia a una actividad como el contexto para el diálogo que siempre se destruye cuando se ejecuta su código.

Además, aunque no estoy seguro de si esta es la mejor manera de saber si su actividad se está ejecutando, consulte esta respuesta para conocer un método para hacerlo:

Compruebe si la actividad está activa

Peter Pascale
fuente
3
No llamar dialog.show()resuelve el problema, pero ¿cuál es la solución para poder seguir mostrando mi diálogo?
natsumiyu
Para mí, estoy llamando Fragment.getContext(), que funciona para API superiores a 21. Pero en Lollipop se bloquea
TheRealChx101
158

Veía este error reportado de vez en cuando desde algunas de mis aplicaciones, y esto es lo que me solucionó:

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

Todas las otras respuestas parecen estar haciendo cosas raras como iterar a través de la lista de actividades en ejecución, pero esto es mucho más simple y parece funcionar.

DiscDev
fuente
6
no resuelve el problema, evita
fallas
6
¡Solo recuerde que debe verificar context instanceof Activityo puede obtener un Exception!
FtheBuilder
3
o puede usar getActivity (). isFinishing () en lugar de context
Nikita Axyonov
Estoy usando API-23. Cuando trato de usar esto en mi MainActivity, que extiende AppCompatActivity. Me muestra un error como Causado por: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController no se puede transmitir a android.app.Activity en com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppController es agregado a mi AndroidMenifest
pavel
No estoy usando ningún diálogo y obtengo este error.
Abdul Waheed
10

una solución alternativa simple es detectar la excepción:

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

No es elegante, pero a veces es fácil cuando tiene que administrar operaciones asincrónicas y no está seguro de si la actividad está activa o no cuando desea mostrar el diálogo.

gerz
fuente
¡Tan feo pero tan hermoso!
Rahul Tiwari
8
  • En mi caso, el problema se debe a que estoy intentando abrir / mostrar el cuadro de diálogo en onPostExecuteAsyncTask

  • Sin embargo, es un método incorrecto showing dialogo cambia la interfaz de usuario onPostExecute.

  • Para eso, debemos verificar que la actividad esté activa, por ejemplo:, !isFinishing() si la actividad no está terminada, solo podemos mostrar nuestro cuadro de diálogo o cambiar la interfaz de usuario.

    @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
fuente
1

Enfrenté exactamente el mismo problema. Vocación'(!isFinishing())' evitó el accidente, pero no pudo mostrar el mensaje de 'alerta'.

Entonces intenté hacer la función de llamada 'estática' , donde se muestra la alerta. Después de eso, no ocurrió ningún bloqueo y también se muestra el mensaje.

Por ejemplo:

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
fuente
1

Después de ejecutar el hilo, agregue estas dos líneas de código y eso resolverá el problema.

Looper.loop();
Looper.myLooper().quit();
Balachandran Muthuraj
fuente
1

Otro caso de uso Desarrollador: Si el WindowManagero la getWindow()que se está llamando en onCreate()o onStart(), o onResume(), una BadTokenExceptionse lanza. Deberá esperar hasta que la vista esté preparada y adjuntada.

Mover el código a lo onAttachedToWindow()resuelve. Puede que no sea una solución permanente, pero por mucho que pude probar, siempre funcionó.

En mi caso, era necesario aumentar el brillo de la pantalla cuando la actividad se hacía visible. La línea getWindow().getAttributes().screenBrightnessdel onResume()resultó en una excepción. Mover el código a onAttachedToWindow()funcionó.

Ram Iyer
fuente
0

Para mí, se solucionó simplemente eliminando la staticpropiedad en los métodos DialogHelper.class (responsable de crear y ocultar el diálogo), ya que tengo propiedades relacionadas con Windowesos métodos

Dasser Basyouni
fuente
0

Bajo dependencyServices nada de lo anterior me ayudó, terminé haciendo lo siguiente:

    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);
        }
    }

Debo usar la "clase doble" porque una interfaz no puede ser estática. L-

Legión
fuente
0

No se puede agregar la ventana: el token no es válido; ¿Tu actividad se está ejecutando?

Este bloqueo generalmente se debe a que su aplicación intenta mostrar un cuadro de diálogo utilizando una actividad finalizada previamente como contexto. Por ejemplo, esto puede suceder si una actividad activa una AsyncTask que intenta mostrar un cuadro de diálogo cuando termina, pero el usuario regresa de la actividad antes de que se complete la tarea.

Recursos externos

Android: visualización de cuadros de diálogo de hilos en segundo plano

Error: BinderProxy @ 45d459c0 no es válido; ¿Tu actividad se está ejecutando?

Bholendra Singh
fuente
0

Lo resolví poniendo esto:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}
Juan L. Antón Santamaria
fuente
Por favor, elija el idioma inglés al publicar
Pedro Coelho