Avoid leaking Activities with AsyncTask

suggest change
A word of caution: AsyncTask has many gotcha’s apart from the memory leak described here. So be careful with this API, or avoid it altogether if you don’t fully understand the implications. There are many alternatives (Thread, EventBus, RxAndroid, etc).

One common mistake with AsyncTask is to capture a strong reference to the host Activity (or Fragment):

class MyActivity extends Activity {
  private AsyncTask<Void, Void, Void> myTask = new AsyncTask<Void, Void, Void>() {

// Don’t do this! Inner classes implicitly keep a pointer to their // parent, which in this case is the Activity!

}
}

This is a problem because AsyncTask can easily outlive the parent Activity, for example if a configuration change happens while the task is running.

The right way to do this is to make your task a static class, which does not capture the parent, and holding a weak reference to the host Activity:

class MyActivity extends Activity {
  static class MyTask extends AsyncTask<Void, Void, Void> {
    // Weak references will still allow the Activity to be garbage-collected
    private final WeakReference<MyActivity> weakActivity;

    MyTask(MyActivity myActivity) {
      this.weakActivity = new WeakReference<>(myActivity);
    }

    @Override
    public Void doInBackground(Void... params) {
      // do async stuff here
    }

    @Override
    public void onPostExecute(Void result) {
      // Re-acquire a strong reference to the activity, and verify
      // that it still exists and is active.
      MyActivity activity = weakActivity.get();
      if (activity == null
          || activity.isFinishing()
          || activity.isDestroyed()) {
        // activity is no longer valid, don't do anything!
        return;
      }

      // The activity is still valid, do main-thread stuff here
    }
  }
}

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents