Fenstertoken android.os.BinderProxy kann nicht hinzugefügt werden. Läuft Ihre Aktivität?

116

Ich versuche über die Facebook-API eine Verbindung zu Facebook herzustellen. Ich folge dem folgenden Beispiel: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

Alles ist in Ordnung, aber wenn ich versuche, Code zu bearbeiten, möchte ich die Dialogpost-Nachricht anzeigen, nachdem die Anmeldung erfolgreich war:

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

Ich erhalte diesen Fehler im 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)

Irgendeine Idee?

Han Tran
quelle
1
Überprüfen Sie die Antwort unten. Ich habe markiert, dass es richtig ist :)
Han Tran
Nur weil Sie die Antwort markiert haben, ändert dies nichts an der Tatsache, dass es sich um eine doppelte Frage handelt. Der andere wurde zuerst gefragt und ist ein identisches Problem mit einer im Wesentlichen identischen Antwort.
Bsara
1
Hast du gesehen, dass meine Frage vor 2 Jahren ist?
Han Tran
1
Also sieh aus wie andere Der Moderator hat einen Fehler, aber du :)) Anw, danke!
Han Tran

Antworten:

127

Dies kann auftreten, wenn Sie den Dialog für einen nicht mehr vorhandenen Kontext anzeigen. Ein häufiger Fall: Wenn die Operation "Dialog anzeigen" nach einer asynchronen Operation ausgeführt wird und während dieser Operation die ursprüngliche Aktivität (die das übergeordnete Element Ihres Dialogs sein soll) zerstört wird. Eine gute Beschreibung finden Sie in diesem Blogbeitrag und in den Kommentaren:

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

Aus dem obigen Stack-Trace geht hervor, dass die Facebook-Bibliothek den Authentifizierungsvorgang asynchron abschaltet und Sie über einen Handler-Callback-Mechanismus (onComplete, der von einem Listener aufgerufen wird) verfügen, mit dem dieses Szenario leicht erstellt werden kann.

Wenn ich dies in meiner App gesehen habe, ist es ziemlich selten und entspricht der Erfahrung im Blog-Beitrag. Bei der Aktivität ist ein Fehler aufgetreten / sie wurde während der Arbeit der AsyncTask zerstört. Ich weiß nicht, wie Ihre Änderung jedes Mal dazu führen könnte, aber vielleicht verweisen Sie auf eine Aktivität als Kontext für den Dialog, der bei der Ausführung Ihres Codes immer zerstört wird?

Auch wenn ich nicht sicher bin, ob dies der beste Weg ist, um festzustellen, ob Ihre Aktivität ausgeführt wird, finden Sie in dieser Antwort eine Methode, um dies zu tun:

Überprüfen Sie, ob die Aktivität aktiv ist

Peter Pascale
quelle
3
Nicht anrufen dialog.show()löst das Problem, aber wie sieht es damit aus, meinen Dialog trotzdem anzeigen zu können?
Natsumiyu
Für mich rufe ich an Fragment.getContext(), was für APIs über 21 funktioniert. Aber auf Lollipop stürzt es ab
TheRealChx101
158

Ab und zu wurde dieser Fehler von einigen meiner Apps gemeldet, und hier ist, was ihn für mich gelöst hat:

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

Alle anderen Antworten da draußen scheinen seltsame Dinge zu tun, wie das Durchlaufen der Liste der laufenden Aktivitäten, aber dies ist viel einfacher und scheint den Trick zu tun.

DiscDev
quelle
6
es löst das Problem nicht, es verhindert Absturz und zeigt auch Dialoge an
YTerle
6
Denken Sie daran, Sie sollten überprüfen, context instanceof Activityoder Sie können eine bekommen Exception!
FtheBuilder
3
oder Sie können getActivity (). isFinishing () anstelle von context
Nikita Axyonov
Ich benutze API-23. Wenn ich versuche, dies in meiner MainActivity zu verwenden, die AppCompatActivity erweitert. Es zeigt mir einen Fehler wie Verursacht durch: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController kann nicht in android.app.Activity unter com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppCon umgewandelt werden hinzugefügt in mein AndroidMenifest
pavel
Ich verwende keinen Dialog und erhalte diesen Fehler.
Abdul Waheed
10

Eine einfache Problemumgehung besteht darin, die Ausnahme abzufangen:

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

Es ist nicht elegant, aber manchmal einfach, wenn Sie asynchrone Vorgänge verwalten müssen und nicht sicher sind, ob die Aktivität aktiv ist oder nicht, wenn Sie den Dialog anzeigen möchten.

gerz
quelle
so hässlich und doch so schön!
Rahul Tiwari
8
  • In meinem Fall ist das Problem aufgetreten, weil versucht wird, das Dialogfeld in onPostExecuteAsyncTask zu öffnen / anzuzeigen

  • Es ist jedoch eine falsche Methode showing dialogoder Ui ändert sich in onPostExecute.

  • Dazu müssen wir überprüfen , ob die Aktivität aktiv ist. Beispiel: !isFinishing() Wenn die Aktivität nicht beendet ist, können wir nur unser Dialogfeld anzeigen oder die Benutzeroberfläche ändern.

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

Ich hatte genau das gleiche Problem. Das Anrufen '(!isFinishing())'verhinderte den Absturz, konnte jedoch die Warnmeldung nicht anzeigen.

Dann habe ich versucht, die aufrufende Funktion 'statisch' zu machen , wo eine Warnung angezeigt wird. Danach ist kein Absturz aufgetreten und es wird auch eine Meldung angezeigt.

Zum Beispiel:

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

Fügen Sie nach dem Ausführen des Threads diese beiden Codezeilen hinzu, um das Problem zu beheben.

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

Ein weiterer Anwendungsfall für Entwickler: Wenn das WindowManageroder getWindow()aufgerufen wird onCreate()oder onStart()oder oder onResume(), BadTokenExceptionwird a ausgelöst. Sie müssen warten, bis die Ansicht vorbereitet und angehängt ist.

Verschieben des Codes, um ihn zu onAttachedToWindow()lösen. Es ist vielleicht keine dauerhafte Lösung, aber so viel ich testen konnte, hat es immer funktioniert.

In meinem Fall musste die Bildschirmhelligkeit erhöht werden, als die Aktivität sichtbar wurde. Die Zeile getWindow().getAttributes().screenBrightnessin der onResume()führte zu einer Ausnahme. Verschieben des Codes auf onAttachedToWindow()funktioniert.

Ram Iyer
quelle
0

Für mich wurde dies behoben, indem nur die staticEigenschaft in den DialogHelper.class-Methoden entfernt wurde (resposble zum Erstellen und Ausblenden des Dialogs), da ich Eigenschaften habe, die sich Windowauf diese Methoden beziehen

Dasser Basyouni
quelle
0

Unter dependencyServices hat mir nichts von alledem geholfen. Am Ende habe ich Folgendes getan:

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

Ich muss die "Doppelklasse" verwenden, da eine Schnittstelle nicht statisch sein kann. L-

Legion
quelle
0

Fenster-Token kann nicht hinzugefügt werden - ist ungültig; Läuft Ihre Aktivität?

Dieser Absturz wird normalerweise dadurch verursacht, dass Ihre App versucht, einen Dialog mit einer zuvor abgeschlossenen Aktivität als Kontext anzuzeigen. Dies kann beispielsweise passieren, wenn eine Aktivität eine AsyncTask auslöst, die versucht, ein Dialogfeld anzuzeigen, wenn es abgeschlossen ist, der Benutzer jedoch vor Abschluss der Aufgabe von der Aktivität zurück navigiert.

Externe Ressourcen

Android - Anzeigen von Dialogen aus Hintergrund-Threads

Fehler: BinderProxy @ 45d459c0 ist ungültig. Läuft Ihre Aktivität?

Bholendra Singh
quelle
0

Ich habe es gelöst, indem ich Folgendes formulierte:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}
Juan L. Antón Santamaria
quelle
Bitte wählen Sie beim Posten die englische Sprache
Pedro Coelho