Play with this demo
In this Activity, you can :
- start an AsyncTask and see the progress ;
- cancel a started AsyncTask ;
- start an AsyncTask, rotate the device and observe that UI is updated as expected ;
- no more memory leak, you can start as many AsyncTasks as you want.
Read below to learn more.
Advanced AsyncTask usage 2/2.
This Activity uses an AsyncTask declared as a static inner class.
The Activity holds a WeakReference on the AsyncTask and the AsyncTask uses a WeakReference on the Activity (2-way weak references).
Memory leak issue
This technique definitely solves the problem : AsyncTask doesn't hold any hard reference to the activity and the other way around.
This way, the AsyncTask itself never prevents the Activity from being garbage collected. There is no memory leak at all using this technique.
Nevertheless, the technique proposed here :
- is really heavy and leads to a bloated game of WeakReferences. It would be clearer and lighter to use Loaders.
- uses a deprecated method : getLastNonConfigurationInstance. This method is not
available anymore in latest APIs (as it used internally by the Loader Framework of Android)
and is not available in the support library class FragmentActivity (for the same reason). In support classes, there is a new method called
: getLastCustomNonConfigurationInstance and this prevents us from proposing a general solution to the AsyncTask memory issue).
- although memory management is fine, it is still possible to get a lot of AsyncTasks queued in the ExecutorService (see previous demo for
more explanations). AsyncTasks should either be cancelled when rotating the device, or we should prevent another identical AsyncTask to be
started if one is already running, this leads to more and more complex code to handle all those situations.
Conclusion on AsyncTasks
This demo Activty illustrates how difficult it is to get a robust implementation of AsyncTasks. It is possible to achieve a working solution with
no memory leak, but not in the same way for all versions of Android (with respect to backward compatibility support library). The conclusion of this serie is that :
Yes, Loaders are the way to go, just forget AsyncTasks for
long running asynchronous jobs.
Loaders offer a more modern implementation of Asynchronous job executions and we will illustrate how to use them in the next serie of this tutorial application.