142 votes

Impossible d'ajouter une fenêtre -- le jeton Android.os.BinderProxy n'est pas valide ; votre activité est-elle en cours d'exécution ?

J'essaie de me connecter à Facebook via l'API Facebook, en suivant cet exemple : https://github.com/facebook/facebook-Android-sdk/tree/master/examples/simple

Tout va bien, mais lorsque j'essaie d'éditer du code, je veux afficher le message du dialogue après la réussite de la connexion comme ceci :

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

Je reçois cette erreur dans le 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)

Une idée ?

182voto

DiscDev Points 8087

Je voyais cette erreur signalée de temps en temps par certaines de mes applications, et voici ce qui l'a résolue pour moi :

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

Toutes les autres réponses semblent faire des choses bizarres comme itérer à travers la liste des activités en cours, mais celle-ci est beaucoup plus simple et semble faire l'affaire.

140voto

Peter Pascale Points 423

Cela peut se produire lorsque vous affichez la boîte de dialogue pour un contexte qui n'existe plus. Un cas courant est celui où l'opération "afficher la boîte de dialogue" suit une opération asynchrone et où, au cours de cette opération, l'activité d'origine (c'est-à-dire le parent de votre boîte de dialogue) est détruite. Pour une bonne description, voir ce billet de blog et les commentaires :

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

D'après la trace de pile ci-dessus, il semble que la bibliothèque facebook déclenche l'opération d'authentification de manière asynchrone, et vous avez un mécanisme Handler - Callback (onComplete appelé sur un listener) qui pourrait facilement créer ce scénario.

Lorsque j'ai vu cela dans mon application, c'était plutôt rare et cela correspondait à l'expérience décrite dans l'article du blog. Quelque chose s'est mal passé pour l'activité/elle a été détruite pendant le travail de l'AsyncTask. Je ne sais pas comment votre modification pourrait aboutir à ce résultat à chaque fois, mais peut-être faites-vous référence à une activité comme contexte pour le dialogue qui est toujours détruit au moment où votre code s'exécute ?

Par ailleurs, bien que je ne sois pas certain qu'il s'agisse de la meilleure façon de savoir si votre activité est en cours, vous trouverez dans cette réponse une méthode pour y parvenir :

Vérifier si l'activité est active

21voto

gerz Points 171

Une solution simple consiste à rattraper l'exception :

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

Ce n'est pas élégant mais parfois facile quand on doit gérer des opérations asynchrones et qu'on n'est pas sûr que l'activité est en cours ou non quand on veut afficher la boîte de dialogue.

13voto

Agilanbu Points 516
  • Dans mon cas, le problème est dû au fait que j'essaie d'ouvrir/afficher une boîte de dialogue dans l'application onPostExecute AsyncTask

  • Toutefois, il s'agit d'une mauvaise méthode de showing dialog ou Ui change en onPostExecute .

  • Pour cela, nous devons vérifier que l'activité est bien active Eg : !isFinishing() Si l'activité n'est pas terminée, nous ne pouvons qu'afficher notre boîte de dialogue ou modifier l'interface utilisateur.

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

1voto

Après avoir exécuté le thread, ajoutez ces deux lignes de code, et le problème sera résolu.

Looper.loop();
Looper.myLooper().quit();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X