Wednesday, March 20, 2013

Is Your AsyncTask Running?

A short note about AsyncTask: Prior to 4.0 (and maybe prior to 3.0, but I haven't tested), AsyncTask.getStatus() might lie to you. If the AsyncTask is canceled, it won't set the status correctly; instead, it will remain RUNNING far after AsyncTask.onCancelled() finishes.

My initial thought was to use AsyncTask.isCancelled(), but you can run into some concurrency issues there if you're trying to gauge whether the AsyncTask is done from another thread.  A cancelled AsyncTask doesn't necessarily end the moment you cancel it; in fact, if you're not checking isCancelled() regularly in doInBackground() then you can end up having the AsyncTask run for a while after you cancel.

My solution is to set a boolean at the end of onCancelled() that will indicate to the system that you got to the end of execution.  Here's an example of writing an AsyncTask where you can properly know when it's been finished:

private class MyAsyncTask extends AsyncTask {
  private boolean mFinishedCancel = false;

  protected Void doInBackground(Void... params) {
    return null; // You'd normally do something here
  }

  protected void onCancelled() {
    mFinishedCancel = true;
  }

  public boolean isFinished() {
    return getStatus() == Status.FINISHED || mFinishedCancel;
  }
}

No comments:

Post a Comment