Suppose you've got a background task running with AsyncTask. At the end of this task (in onPostExecute()), you display a Dialog informing the user of success or failure. This seems to be pretty cut and dry, but there's a catch - sometimes you'll get this error:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4479b390 is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:468)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:239)
at android.app.Activity.showDialog(Activity.java:2488)
...
The problem lies in the fact that the AsyncTask can continue running past when the Activity itself has been finished. If a user hits the "back" button on your Activity while the AsyncTask is running, you will end up calling showDialog() after the Activity itself is finished.
My initial fix was to try to augment onCreateDialog() to handle finished activities, but unfortunately, there's no way to cancel dialog creation once you've called showDialog(); you'll cause errors returning null from onCreateDialog(). Thus, the only solution is to play it safe before you call showDialog():
protected void onPostExecute(Object result) {
if (!isFinishing()) {
showDialog(MY_DIALOG_ID);
}
}