Co to za błąd ... Nie znalazłem żadnej dyskusji na temat tego błędu w społeczności stackoverflow Szczegółowe: -
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)
Odpowiedzi:
Dzieje się tak najprawdopodobniej, ponieważ próbujesz wyświetlić okno dialogowe po wykonaniu wątku w tle, gdy działanie jest niszczone.
Widziałem ten błąd zgłaszany od czasu do czasu z niektórych moich aplikacji, gdy działanie wywołujące okno dialogowe kończyło się z jakiegoś powodu, gdy próbowało wyświetlić okno dialogowe. Oto, co mi to rozwiązało:
Używam tego do obejścia problemu w starszych wersjach Androida od kilku lat i od tego czasu nie widziałem awarii.
źródło
Zmierzyłem się z tym samym problemem i użyłem kodu zaproponowanego przez DiscDev powyżej z niewielkimi zmianami w następujący sposób:
źródło
jeśli okno dialogowe rozwiązuje ten problem z powodu wątku, powinieneś to zrobić w wątku UI w ten sposób: -
źródło
Ten błąd występuje, gdy jest wyświetlane okno dialogowe kontekstu, który już nie istnieje.
Przed wywołaniem
.show()
sprawdź, czy aktywność / kontekst się nie kończyźródło
Napotkałem ten błąd, gdy miałem
countDownTimer
w mojej aplikacji. Miał metodę wywołującą GameOver w mojej aplikacji jakoale w rzeczywistości gra mogła się zakończyć przed upływem czasu z powodu niewłaściwego kliknięcia użytkownika (była to gra polegająca na klikaniu). Kiedy więc patrzyłem na okno dialogowe Koniec gry po np. 20 sekundach, zapomniałem anulować,
countDownTimer
więc po upływie tego czasu okno dialogowe pojawiło się ponownie. Lub z jakiegoś powodu zawiesił się z powyższym błędem.źródło
Rozwiązanie tego jest dość proste. Po prostu sprawdź, czy działanie przechodzi przez fazę kończenia przed wyświetleniem okna dialogowego:
zobacz więcej tutaj
źródło
W moim przypadku problem polegał na tym, że
Context
było to słabe odniesienie w klasie, która się rozszerzaHandler
. Potem przechodziłemMessenger
, co otacza przewodnika, przez aIntent
doService
. Robiłem to za każdym razem, gdy aktywność pojawiała się na ekranie wonResume()
metodzie.Jak więc rozumiesz, Messenger został serializowany wraz z jego polami (w tym kontekstem), ponieważ jest to jedyny sposób na przekazywanie obiektów za pomocą
Intent
- w celu ich serializacji. W tym momencie, gdy Messenger został przekazany do usługi, sama aktywność nadal nie była gotowa do wyświetlania okien dialogowych, ponieważ jest w innym stanie (mówiąc o onResume (), który jest całkowicie inny niż wtedy, gdy aktywność jest już na ekranie). Więc kiedy messenger został zdeserializowany, kontekst nadal był w stanie wznowienia, podczas gdy aktywność faktycznie była już na ekranie. Ponadto deserializacja przydziela pamięć dla nowego obiektu, który jest zupełnie inny niż oryginalny.Rozwiązaniem jest po prostu wiązanie się z usługą za każdym razem, gdy jej potrzebujesz, zwracanie segregatora, który ma metodę taką jak „setMessenger (komunikator Messenger)” i wywoływanie go, gdy jesteś powiązany z usługą.
źródło
Rozwiązuję ten problem za pomocą
WeakReference<Activity>
jako kontekstu. Katastrofa nigdy się nie powtórzyła. Oto przykładowy kod w Kotlinie:Klasa menedżera dialogów:
I pokazujesz takie okno dialogowe:
Jeśli chcesz być super-duper zabezpieczony przed awariami. Zamiast
builder.create().show()
używać:Oto
safeShow
metoda:Jest to podobna metoda, której możesz użyć do bezpiecznego zamknięcia okna dialogowego:
źródło
co powiesz na utworzenie nowej instancji tego okna dialogowego, które chcesz wywołać? Właściwie właśnie napotkałem ten sam problem i to właśnie robię. więc zamiast:
co powiesz na to?
więc zamiast po prostu sprawdzać, czy wyświetlanie okna dialogowego jest bezpieczne, czy też nie, myślę, że znacznie bezpieczniej jest, jeśli po prostu utworzymy nową instancję, aby wyświetlić okno dialogowe.
Podobnie jak ja, w moim przypadku próbowałem utworzyć jedną instancję (z Fragment onCreate ) i wywołać instancję tych okien dialogowych w innej zawartości adapterList, co spowoduje wyświetlenie błędu „czy Twoja aktywność jest uruchomiona” - błąd . Pomyślałem, że to dlatego, że po prostu tworzę jedną instancję (z onCreate), a następnie jest ona niszczona, więc kiedy próbowałem wywołać ją z innej listy adapterów , wywołuję okno dialogowe ze starej instancji.
Nie jestem pewien, czy moje rozwiązanie jest przyjazne dla pamięci, czy nie, ponieważ nie próbowałem go profilować, ale działa (cóż, jest bezpieczne, jeśli nie utworzysz zbyt wielu instancji)
źródło