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?
Antworten:
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
quelle
dialog.show()
löst das Problem, aber wie sieht es damit aus, meinen Dialog trotzdem anzeigen zu können?Fragment.getContext()
, was für APIs über 21 funktioniert. Aber auf Lollipop stürzt es abAb und zu wurde dieser Fehler von einigen meiner Apps gemeldet, und hier ist, was ihn für mich gelöst hat:
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.
quelle
context instanceof Activity
oder Sie können eine bekommenException
!Eine einfache Problemumgehung besteht darin, die Ausnahme abzufangen:
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.
quelle
In meinem Fall ist das Problem aufgetreten, weil versucht wird, das Dialogfeld in
onPostExecute
AsyncTask zu öffnen / anzuzeigenEs ist jedoch eine falsche Methode
showing dialog
oder Ui ändert sich inonPostExecute
.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.quelle
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:
quelle
Fügen Sie nach dem Ausführen des Threads diese beiden Codezeilen hinzu, um das Problem zu beheben.
quelle
Ein weiterer Anwendungsfall für Entwickler: Wenn das
WindowManager
odergetWindow()
aufgerufen wirdonCreate()
oderonStart()
oder oderonResume()
,BadTokenException
wird 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().screenBrightness
in deronResume()
führte zu einer Ausnahme. Verschieben des Codes aufonAttachedToWindow()
funktioniert.quelle
Für mich wurde dies behoben, indem nur die
static
Eigenschaft in den DialogHelper.class-Methoden entfernt wurde (resposble zum Erstellen und Ausblenden des Dialogs), da ich Eigenschaften habe, die sichWindow
auf diese Methoden beziehenquelle
Unter dependencyServices hat mir nichts von alledem geholfen. Am Ende habe ich Folgendes getan:
Ich muss die "Doppelklasse" verwenden, da eine Schnittstelle nicht statisch sein kann. L-
quelle
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?
quelle
Ich habe es gelöst, indem ich Folgendes formulierte:
quelle