2011-10-18 17 views
83

Co to jest błąd ... ja nie znalazłem żadnej dyskusji na temat tego błędu w społeczności stackoverflow Szczegółowe: -Błąd: BinderProxy @ 45d459c0 jest nieprawidłowy; czy twoja aktywność jest uruchomiona?

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 [email protected] 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) 
+0

Możliwy duplikat [Nie można dodać okna - token android.os.BinderProxy jest niepoprawny; czy twoja aktywność jest uruchomiona?] (https: // stackoverflow.com/questions/9529504/nie można dodać-window-token-android-os-binderproxy-is-not-valid-is-your-activ) – Pod

Odpowiedz

214

Jest to najprawdopodobniej dzieje się tak, ponieważ próbujesz wyświetlić okno dialogowe po wykonaniu wątku w tle, podczas gdy działanie jest niszczone.

Widziałem ten błąd od czasu do czasu zgłaszany przez niektóre z moich aplikacji, gdy działanie wywołujące dialog kończyło się z jakiegoś powodu podczas próby wyświetlenia okna dialogowego. Oto, co to dla mnie rozwiązany:

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

Używam tego obejścia problemu na starszych wersjach Androida już od kilku lat, a nie od widział katastrofę.

+0

To faktycznie robi lewę! ale czy istnieje sposób na otwarcie okna dialogowego, nawet jeśli tak się stanie? Naprawdę nie wiem, jak zarządzać dialogiem, kiedy to się dzieje. Jakieś sugestie? Z góry dziękuję! –

+0

@CarlaStabile hi! Jedynym sposobem, w jaki mogę pokazać okno dialogowe, kiedy to się stanie, byłoby uzyskanie prawidłowego kontekstu dla działania, które nie jest zakończone - zależałoby od tego, gdzie wywołujesz ten kod i czy masz sposób na odzyskanie kontekst z innej, nie kończącej się działalności. – DiscDev

+3

Dzięki za milion! Dla mnie błąd (z komunikatem o błędzie powyżej) miał miejsce, gdy nacisnąłem przycisk Wstecz, zanim okno dialogowe się pojawiło. Tak więc kod będzie kontynuowany i spróbuje go pokazać, mimo że byłem w innej działalności. Ale to zatrzymało awarię i z łatwością poszedłem do nowej działalności! – Azurespot

1

Napotkano ten błąd, gdy miałem countDownTimer w mojej aplikacji. Miał metodę wywoływania GameOver w mojej aplikacji jako

public void onFinish() { 
    GameOver(); 
} 

ale faktycznie gra może się skończyć, zanim czas się skończył spowodowane niewłaściwym kliknięciem użytkownika (to była gra kliknięcie). Kiedy więc patrzyłem na okno dialogowe "Po zakończeniu gry", np. 20 sekund, zapomniałem anulować countDownTimer, więc gdy czas się skończył, ponownie pojawiło się okno dialogowe. Lub z jakiegoś powodu uległ awarii z powyższym błędem.

4

I w obliczu tego samego problemu i używany kod zaproponowany przez DiscDev powyżej z niewielkimi zmianami w następujący sposób:

if (!MainActivity.this.isFinishing()){ 
    alertDialog.show(); 
} 
+2

Witaj, musisz opracować (komentarz do kodu lub post), dlaczego to zmieniłeś. Podaj także link do sugestii, a nie do profilu użytkownika. –

+0

Zmieniłem, ponieważ średnia kontekstowa (Aktywność) była MainActivity.this dla mojej sprawy. Masz również rację odnośnie linku do profilu użytkownika, ale pomyślałem, że możesz go znaleźć powyżej. –

0

Rozwiązaniem tego problemu jest dość proste. Wystarczy sprawdzić, czy aktywny przeżywa fazie wykończeniowej przed wyświetleniem Dialog:

private Handler myHandler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
    switch (msg.what) { 
     case DISPLAY_DLG: 
     if (!isFinishing()) { 
     showDialog(MY_DIALOG); 
     } 
     break; 
    } 
    } 
}; 

zobacz więcej here

0

W moim przypadku problemem było to, że Context utrzymywano jako słaby punkt odniesienia w klasie, która rozciąga Handler . Następnie przechodziłem pod numer Messenger, który owija uchwyt, przez Intent do Service. Robiłem to za każdym razem, gdy aktywność pojawiała się na ekranie w metodzie onResume().

Tak jak rozumiesz, posłaniec był serializowany razem z jego polami (w tym kontekstem), ponieważ jest to jedyny sposób przekazywania obiektów przy użyciu Intent - w celu serializacji. I w tym momencie, kiedy komunikator został przekazany do usługi, sama czynność nadal nie była gotowa do pokazania okien dialogowych, ponieważ jest w innym stanie (powiedzmy onResume(), który jest zupełnie inny niż kiedy działanie jest już na ekranie). Kiedy posłaniec został zserializowany, kontekst nadal znajdował się w stanie wznowienia, podczas gdy działanie faktycznie było już na ekranie. Ponadto deserializacja przydziela pamięć dla nowego obiektu, który jest zupełnie inny niż oryginalny.

Rozwiązaniem jest po prostu powiązanie usługi za każdym razem, gdy jej potrzebujesz i zwrócenie segregatora, który ma metodę taką jak "setMessenger (Messenger messenger)" i wywołanie go, gdy jesteś powiązany z usługą.

Powiązane problemy