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

116

J'essaye de me connecter à Facebook via l'API Facebook, je suis cet exemple: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

Tout va bien, mais lorsque j'essaie de modifier du code, je veux dire que je veux afficher le message de publication de la boîte de dialogue une fois la connexion réussie, 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?

Han Tran
la source
1
Vérifiez la réponse ci-dessous. J'ai noté que c'est correct :)
Han Tran
Le fait que vous ayez marqué la réponse ne change pas le fait qu'il s'agit d'une question en double. L'autre a été posée en premier et est un problème identique avec une réponse essentiellement identique.
bsara
1
Avez-vous vu que ma question remonte à 2 ans?
Han Tran
1
Alors regardez comme les autres Le modérateur a une erreur mais vous :)) Anw, merci!
Han Tran

Réponses:

127

Cela peut se produire lorsque vous affichez la boîte de dialogue pour un contexte qui n'existe plus. Un cas courant - si l'opération «Afficher la boîte de dialogue» est après une opération asynchrone, et pendant cette opération, l'activité d'origine (qui doit être le parent de votre boîte de dialogue) est détruite. Pour une bonne description, consultez ce billet de blog et ses commentaires:

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

À partir de la trace de pile ci-dessus, il semble que la bibliothèque Facebook tourne de manière asynchrone l'opération d'authentification et que vous disposez d'un mécanisme Handler - Callback (onComplete appelé sur un écouteur) qui pourrait facilement créer ce scénario.

Quand j'ai vu cela rapporté dans mon application, c'est assez rare et correspond à l'expérience du billet de blog. Une erreur s'est produite pour l'activité / elle a été détruite pendant le travail de l'AsyncTask. Je ne sais pas comment votre modification pourrait entraîner cela à chaque fois, mais peut-être que vous faites référence à une activité comme contexte de la boîte de dialogue qui est toujours détruite au moment où votre code s'exécute?

De plus, même si je ne suis pas sûr que ce soit la meilleure façon de savoir si votre activité est en cours d'exécution, consultez cette réponse pour une méthode de le faire:

Vérifiez si l'activité est active

Peter Pascale
la source
3
Ne pas appeler dialog.show()résout le problème, mais quel est le contournement pour pouvoir toujours afficher ma boîte de dialogue?
natsumiyu
Pour moi, j'appelle Fragment.getContext(), qui fonctionne pour les API au-dessus de 21. Mais sur Lollipop, il plante
TheRealChx101
158

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 étranges, comme parcourir la liste des activités en cours d'exécution, mais c'est beaucoup plus simple et semble faire l'affaire.

DiscDev
la source
6
cela ne résout pas le problème, cela empêche les plantages et l'affichage des dialogues aussi
YTerle
6
N'oubliez pas que vous devriez vérifier context instanceof Activityou vous pourriez obtenir un Exception!
FtheBuilder
3
ou vous pouvez utiliser getActivity (). isFinishing () au lieu de context
Nikita Axyonov
J'utilise l'API-23. Quand j'essaye d'utiliser ceci dans mon MainActivity qui étend AppCompatActivity. Il me montre une erreur comme Caused by: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController ne peut pas être converti en android.app.Activity à com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) ajouté à mon AndroidMenifest
pavel
Je n'utilise aucun dialogue et j'obtiens cette erreur.
Abdul Waheed le
11

une solution de contournement simple consiste à intercepter l'exception:

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

Ce n'est pas élégant mais parfois facile lorsque vous devez gérer des opérations asynchrones et que vous ne savez pas si l'activité est en cours ou non lorsque vous souhaitez afficher la boîte de dialogue.

Gerz
la source
1
si moche et si belle!
Rahul Tiwari
8
  • Dans mon cas, le problème est survenu parce que j'essaie d'ouvrir / afficher la boîte de dialogue dans onPostExecuteAsyncTask

  • Cependant, c'est une mauvaise méthode showing dialogou Ui change dans onPostExecute.

  • Pour cela, nous devons vérifier que l'activité est active Par exemple:, !isFinishing() si l'activité n'est pas terminée, nous ne pouvons que montrer 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());
                            }
                        }
                    }
                });
    }
Agilanbu
la source
1

J'ai fait face exactement au même problème. L'appel a '(!isFinishing())'empêché le crash, mais n'a pas pu afficher le message «d'alerte».

Ensuite, j'ai essayé de rendre la fonction d'appel «statique» , où l'alerte est affichée. Après cela, aucun plantage ne s'est produit et le message s'affiche également.

Par exemple:

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
la source
1

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

Looper.loop();
Looper.myLooper().quit();
Balachandran Muthuraj
la source
1

Un autre cas d'utilisation pour les développeurs: si le WindowManagerou getWindow()est appelé sur onCreate()ou onStart()ou onResume(), un BadTokenExceptionest lancé. Vous devrez attendre que la vue soit préparée et jointe.

Déplacer le code pour le onAttachedToWindow()résoudre. Ce n'est peut-être pas une solution permanente, mais autant que j'ai pu tester, cela a toujours fonctionné.

Dans mon cas, il était nécessaire d'augmenter la luminosité de l'écran lorsque l'activité devenait visible. La ligne getWindow().getAttributes().screenBrightnessdans le onResume()aboutit à une exception. Déplacement du code sur onAttachedToWindow()travaillé.

Ram Iyer
la source
0

Pour moi, cela a été corrigé en supprimant simplement la staticpropriété dans les méthodes DialogHelper.class (resposble pour créer et masquer la boîte de dialogue), car j'ai des propriétés liées à Windowces méthodes

Dasser Basyouni
la source
0

Sous dependencyServices, rien de ce qui précède ne m'a aidé, j'ai fini par faire comme ci-dessous:

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

Je dois utiliser la "double classe" car une interface ne peut pas être statique. L-

Légion
la source
0

Impossible d'ajouter la fenêtre - le jeton n'est pas valide; votre activité est-elle en cours?

Ce plantage est généralement dû au fait que votre application tente d'afficher une boîte de dialogue en utilisant une activité précédemment terminée comme contexte. Par exemple, cela peut se produire si une activité déclenche une AsyncTask qui tente d'afficher une boîte de dialogue lorsqu'elle est terminée, mais que l'utilisateur revient de l'activité avant que la tâche ne soit terminée.

Ressources externes

Android - Affichage des boîtes de dialogue à partir des threads d'arrière-plan

Erreur: BinderProxy @ 45d459c0 n'est pas valide; votre activité est-elle en cours?

Bholendra Singh
la source
0

Je l'ai résolu en mettant ceci:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}
Juan L. Antón Santamaria
la source
S'il vous plaît, choisissez la langue anglaise lors de la publication
Pedro Coelho