2012-01-10 13 views
8

Witam Mam do czynienia z problemem w oknie dialogowym wiadomości, zamykanie mojego kodu jest tutaj.Wyjątek wyjątkowego tokena menedżera okien

w Create:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.email_result); 

    email_result = (Button) findViewById(R.id.email_result_btn); 
    email_result.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 


      if (diffdays > 365) { 

       h.sendEmptyMessage(0); 
       } 
     } 
    } 
    } 

Moja Handler:

private Handler h = new Handler() { 
    public void handleMessage(Message msg) { 
      showMessageDialog("Sorry, you cannot email entries which are earlier than one year ago."); 
    } 
}; 

ShowMessageDialog Metoda:

public void showMessageDialog(String nMessage) { 

    alertDialog = new Dialog(Email_Result.this); 
    AlertDialog.Builder customBuilder = new AlertDialog.Builder(
      Email_Result.this); 
    customBuilder.setMessage(nMessage); 
    customBuilder.setPositiveButton(getString(R.string.ok), 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        alertDialog.dismiss(); 
       } 
      }); 
    alertDialog = customBuilder.create(); 
    alertDialog.setCancelable(true); 
    alertDialog.show(); 
} 

Error Log

01-11 12:08:24.470: ERROR/AndroidRuntime(325): FATAL EXCEPTION: main 
01-11 12:08:24.470: ERROR/AndroidRuntime(325): android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running? 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.view.ViewRoot.setView(ViewRoot.java:505) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.view.Window$LocalWindowManager.addView(Window.java:424) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.app.Dialog.show(Dialog.java:241) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at com.stress1.Email_Result.showMessageDialog(Email_Result.java:207) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at com.stress1.Email_Result$2.onClick(Email_Result.java:81) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.view.View.performClick(View.java:2408) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.view.View$PerformClick.run(View.java:8816) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.os.Handler.handleCallback(Handler.java:587) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.os.Handler.dispatchMessage(Handler.java:92) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.os.Looper.loop(Looper.java:123) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at java.lang.reflect.Method.invoke(Method.java:521) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
01-11 12:08:24.470: ERROR/AndroidRuntime(325):  at dalvik.system.NativeStart.main(Native Method) 
+1

proszę umieszczać LogCat ** ** ten błąd występuje zwykle, gdy używasz 'ActivityGroup' –

+0

Dlaczego używasz programu obsługi, aby wyświetlić okno dialogowe. możesz również wywołać showMessageDialog z twojego onclick. jaki jest pożytek z obsługi w tym kodzie? Sprawdź ten link, dlaczego potrzebujemy obsługi w naszej klasie. http://developer.android.com/reference/android/os/Handler.html –

+0

Próbowałem bez Handlera, ale dostałem ten sam błąd, zobacz mój błąd także –

Odpowiedz

25

Wygląda na to, że wyjątek występuje po wywołaniu metody show() w oknie dialogowym. Spróbuj użyć następującego kodu, który mógłby obejście problemu:

try { 
     alertDialog.show(); 
} catch(Exception e){ 
    // WindowManager$BadTokenException will be caught and the app would not display 
    // the 'Force Close' message 
} 

Taki problem pojawia się, gdy aktywność próbuje wyświetlić AlertDialog po to został już zakończony. Warto więc przyjrzeć się bliżej, jak działa Twój kod.

Również metoda showMessageDialog może zostać uproszczona w następujący sposób: (! IsFinishing)

public void showMessageDialog(String nMessage) { 

    AlertDialog.Builder customBuilder = new AlertDialog.Builder(Email_Result.this); 
    customBuilder.setMessage(nMessage); 
    customBuilder.setPositiveButton(getString(R.string.ok),new DialogInterface.OnClickListener(){ 
     @Override    
     public void onClick(DialogInterface dialog, int which) { 
       dialog.dismiss(); 
     } 
    }); 
    customBuilder.setCancelable(true); 
    customBuilder.show(); 
} 
+2

w odpowiedzi na: "taki problem pojawia się, gdy aktywność próbuje wyświetla AlertDialog po jego zakończeniu. " ... WindowManager.BadTokenException może być również zgłoszony, jak odkryłem, na myAlertDialog.show(), gdy został zbudowany przy użyciu "new AlertDialog.Builder (myActivity.getApplicationContext())". Rozwiązanie było dwuetapowe: 1 - utworzyć statyczne odniesienie do singleton w całej aplikacji do myActivity, 2 - użyć myActivity jako kontekstu Buildera. –

+2

@TomPace - Wędrujesz tam na niebezpiecznych wodach, ponieważ statyczne odniesienie do kontekstu wiąże się z wyciekiem pamięci. Poza tym nie widzę rozsądnej przyczyny tego rozwiązania. – Abhijit

+0

Jakie jest prawdopodobieństwo wycieku, gdy używam kodu typu destructor "myStaticRef = null;" ? Minęło trochę czasu, odkąd zajmowałem się pamięcią Java, zakładając, że odśmiecanie działa. Ale znam techniki zarządzania pamięcią od C i Obj-C. Mimo to, muszę być świadomy. Proszę poinformować! –

4

Wystarczy dodać, jeśli w kodzie tak:

private Handler h = new Handler() { 
    public void handleMessage(Message msg) { 
      if(!isFinishing) 
      showMessageDialog("Sorry, you cannot email entries which are earlier than one year ago."); 
    } 
}; 
+0

To było rozwiązanie mojego pytania, dziękuję :) http: // stackoverflow .pl/questions/24467391/android-progressdialog-show-windowmanager-token-not-valid –