Wednesday, December 30, 2009

Android Dialogs Created From Threads

There are a lot of issues with Dialogs, but I've run into one recently that deserves mention.

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);
}
}

5 comments:

  1. yeah.. I faced a similar issue.. and used ur workaround.. thnx...

    ReplyDelete
  2. Many thanks for you input, I saved many hours. :)

    ReplyDelete
  3. Thank you very very much... I was struggling a lot to fix this...

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete