Aysnc task are specialized threads that are still meant to be used with your apps GUI but whilst keeping resource-heavy tasks of the UI thread. So when stuff like updating lists, changing your views etc require you to do some fetch operations or update operations, you should use async tasks so that you can keep these operations off the UI thread but note that these operations are still connected to the UI somehow.
For longer-running tasks, which don't require UI updation, you can use services instead because they can live even without a UI.
So for short tasks, use async tasks because they can get killed by the OS after your spawning activity dies (usually will not die mid-operation but will complete its task). And for long and repetitive tasks, use services instead.
Because AsyncTask, by default, uses a thread pool that you did not create. Never tie up resources from a pool that you did not create, as you do not know what that pool's requirements are. And never tie up resources from a pool that you did not create if the documentation for that pool tells you not to, as is the case here.
In particular, starting with Android 3.2, the thread pool used by AsyncTask by default (for apps with android:targetSdkVersion set to 13 or higher) has only one thread in it -- if you tie up this thread indefinitely, none of your other tasks will run.
It is a very good question, it takes time as an Android Programmer to fully understand the issue. Indeed AsyncTask have two main issues that are related :
They are poorly tied to the activity life cycle
They create memory leaks very easily.
Inside the RoboSpice Motivations app (available on Google Play) we answer that question in detail. It will give an in-depth view of AsyncTasks, Loaders, their features and drawbacks and also introduce you to an alternative solution for network requests : RoboSpice.
Network requests are a common requirement in Android and are by nature long running operations
.
Here is an excerpt from the app :
The AsyncTask and Activity life cycle
AsyncTasks don't follow Activity instances' life cycle. If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die. It will go on living until it completes.
And when it completes, the AsyncTask won't update the UI of the new Activity. Indeed it updates the former instance of the activity that
is not displayed anymore. This can lead to an Exception of the type java.lang.IllegalArgumentException: View not attached to window manager if you
use, for instance, findViewById to retrieve a view inside the Activity.
Memory leak issue
It is very convenient to create AsyncTasks as inner classes of your Activities. As the AsyncTask will need to manipulate the views
of the Activity when the task is complete or in progress, using an inner class of the Activity seems convenient : inner classes can
access directly any field of the outer class.
Nevertheless, it means the inner class will hold an invisible reference on its outer class instance : the Activity.
On the long run, this produces a memory leak : if the AsyncTask lasts for long, it keeps the activity "alive"
whereas Android would like to get rid of it as it can no longer be displayed. The activity can't be garbage collected and that's a central
mechanism for Android to preserve resources on the device.
It is really a very very bad idea to use AsyncTasks for long running operations. Nevertheless, they are fine for short living ones such as updating a View after 1 or 2 seconds.
I encourage you to download the RoboSpice Motivations app, it really explains this in-depth and provides samples and demonstrations of the different ways to do some background operations.
The problem with AsyncTask is that if it is defined as non-static inner class of the activity, it will have a reference to activity. In the scenario where activity the container of async task finishes, but the background work in AsyncTask continues, the activity object will not be garbage collected as there is a reference to it, this causes the memory leak.
But still, it is a good idea to use it for simple and quick background tasks. To develop app with clean code, it is better to use RxJava to run complex background tasks and updating UI with results from it.