Was ist dieser Fehler? Ich habe keine Diskussion zu diesem Fehler in der Stackoverflow-Community gefunden. Detailliert: -
10-18 23:53:11.613: ERROR/AndroidRuntime(3197): Uncaught handler: thread main exiting due to uncaught exception
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@45d459c0 is not valid; is your activity running?
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.view.ViewRoot.setView(ViewRoot.java:468)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.view.Window$LocalWindowManager.addView(Window.java:424)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.app.Dialog.show(Dialog.java:239)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at com.vishal.contacte.Locationlistener$MyLocationListener.onLocationChanged(Locationlistener.java:86)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:179)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.location.LocationManager$ListenerTransport.access$000(LocationManager.java:112)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:128)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.os.Looper.loop(Looper.java:123)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at android.app.ActivityThread.main(ActivityThread.java:4363)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at java.lang.reflect.Method.invokeNative(Native Method)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at java.lang.reflect.Method.invoke(Method.java:521)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
10-18 23:53:11.658: ERROR/AndroidRuntime(3197): at dalvik.system.NativeStart.main(Native Method)
Antworten:
Dies geschieht höchstwahrscheinlich, weil Sie versuchen, nach der Ausführung eines Hintergrundthreads ein Dialogfeld anzuzeigen, während die Aktivität zerstört wird.
Dieser Fehler wurde gelegentlich von einigen meiner Apps gemeldet, als die Aktivität, die den Dialog aufruft, aus irgendeinem Grund beendet wurde, als versucht wurde, einen Dialog anzuzeigen. Folgendes hat es für mich gelöst:
Ich benutze dies seit einigen Jahren, um das Problem bei älteren Android-Versionen zu umgehen, und habe den Absturz seitdem nicht mehr gesehen.
quelle
Ich hatte das gleiche Problem und verwendete den von DiscDev oben vorgeschlagenen Code mit geringfügigen Änderungen wie folgt:
quelle
Wenn der Dialog dieses Problem aufgrund des Threads löst, sollten Sie dies auf dem UI-Thread folgendermaßen ausführen: -
quelle
Dieser Fehler tritt auf, wenn Sie das Dialogfeld für einen nicht mehr vorhandenen Kontext anzeigen.
.show()
Überprüfen Sie vor dem Aufruf, ob die Aktivität / der Kontext nicht beendet istquelle
Ich bin auf diesen Fehler gestoßen, als ich einen
countDownTimer
in meiner App hatte. Es gab eine Methode, die GameOver in meiner App als aufriefTatsächlich konnte das Spiel jedoch aufgrund eines falschen Klicks des Benutzers vor Ablauf der Zeit beendet sein (es war ein Klickspiel). Als ich nach z. B. 20 Sekunden das Dialogfeld "Spielende" betrachtete, vergaß ich
countDownTimer
, das Dialogfeld abzubrechen. Sobald die Zeit abgelaufen war, wurde das Dialogfeld erneut angezeigt. Oder aus irgendeinem Grund mit dem obigen Fehler abgestürzt.quelle
Die Lösung dafür ist ziemlich einfach. Testen Sie einfach, ob die Aktivität ihre Abschlussphase durchläuft, bevor Sie den Dialog anzeigen:
Sehen Sie hier mehr
quelle
In meinem Fall bestand das Problem darin, dass
Context
es als schwache Referenz in der erweiterten Klasse beibehalten wurdeHandler
. Dann ging ich vorbeiMessenger
, das wickelt den Handler durch einIntent
zu einService
. Ich tat dies jedes Mal, wenn die Aktivität in deronResume()
Methode auf dem Bildschirm erschien .Wie Sie verstehen, wurde Messenger zusammen mit seinen Feldern (einschließlich Kontext) serialisiert, da dies die einzige Möglichkeit ist, Objekte mit
Intent
- zu serialisieren. Zu dem Zeitpunkt, als Messenger an den Dienst übergeben wurde, war die Aktivität selbst noch nicht bereit, Dialoge anzuzeigen, da sie sich in einem anderen Zustand befindet (inResume () heißt das absolut anders, als wenn die Aktivität bereits auf dem Bildschirm angezeigt wird). Als der Messenger deserialisiert wurde, befand sich der Kontext noch im Wiederaufnahmezustand, während die Aktivität tatsächlich bereits auf dem Bildschirm angezeigt wurde. Darüber hinaus weist die Deserialisierung Speicher für ein neues Objekt zu, das sich vollständig vom ursprünglichen unterscheidet.Die Lösung besteht darin, jedes Mal, wenn Sie ihn benötigen, an den Dienst zu binden und einen Ordner mit einer Methode wie "setMessenger (Messenger Messenger)" zurückzugeben und aufzurufen, wenn Sie an den Dienst gebunden sind.
quelle
Ich löse dieses Problem, indem ich es
WeakReference<Activity>
als Kontext verwende. Der Absturz ist nie wieder aufgetreten. Hier ist ein Beispielcode in Kotlin:Dialog Manager Klasse:
Und Sie zeigen den Dialog folgendermaßen:
Wenn Sie vor Abstürzen geschützt sein wollen. Anstelle von
builder.create().show()
Verwendung:Dies ist die
safeShow
Methode:Dies ist eine ähnliche Methode, mit der Sie den Dialog sicher schließen können:
quelle
Wie wäre es mit einer neuen Instanz dieses Dialogfelds, das Sie aufrufen möchten? Ich bin gerade auf das gleiche Problem gestoßen, und genau das mache ich. also eher als:
Wie wäre es damit?
Anstatt nur zu überprüfen, ob es sicher ist oder nicht, den Dialog anzuzeigen, ist es meiner Meinung nach viel sicherer, wenn wir nur eine neue Instanz erstellen , um den Dialog anzuzeigen.
Wie ich habe ich in meinem Fall versucht, eine Instanz (aus einem Fragment onCreate ) zu erstellen und die Instanz dieses Dialogfelds in einem anderen Inhalt von adapterList aufzurufen. Dies führt zu dem Fehler " Läuft Ihre Aktivität ? " . Ich dachte, das lag daran, dass ich nur eine Instanz (aus onCreate) erstelle und sie dann zerstört wird. Als ich versuchte, sie von einer anderen Adapterliste aus aufzurufen, rief ich den Dialog von einer alten Instanz aus auf.
Ich bin nicht sicher, ob meine Lösung speicherfreundlich ist oder nicht, da ich nicht versucht habe, sie zu profilieren, aber sie funktioniert (sicher ist es sicher, wenn Sie nicht zu viele Instanzen erstellen).
quelle