Running asynchronous tasks off of the UI thread then modifying the UI is a common issue in android development, so I decided to take some time, research, and play around with different techniques and find what works best for me.
What I considered important factors:
Activity
or Fragment
should be kept clean of as much of thread management as possibleHere is the summary of my impressions (which may be wrong and some are just opinions) about the various methods:
I was using simple AsyncTask
without LoaderManager
when I first jumped into Android:
AsyncTaskManager
to manage them with the activity life cycle.This seems to be the recommended way to do this, so I researched it a bit:
Fragment
life cycle, and from my understanding basically just restarts the tasks if necessary. It doesn't seem to be able to receive the results of a task started before an activity was restarted after the activity restarts.Parcelable
or Serialiazable
to go into a Bundle
object.This is the method I settled on:
So I came to the conclusion that using Handler
, Threads
, and Messages
is a much better solution, but I'm convinced I'm missing something because nearly everywhere I looked the recommendation was to use the AsyncTaskLoader
method. What am I missing?
Thanks for the input.
Official Reason for Deprecation of AsyncTaskAsyncTask was intended to enable proper and easy use of the UI thread. However, the most common use case was for integrating into UI, and that would cause Context leaks, missed callbacks, or crashes on configuration changes.
Question 4. When the user rotates the device, how do AsyncTask and AsyncTaskLoader behave differently if they are in the process of running a task in the background? A running AsyncTask becomes disconnected from the Activity even though it keeps executing.
AsyncTaskLoader is used to perform an asynchronous task in the background of the application, so the user can also interact with the application during that process. As soon as the task is completed, the result will be updated to the interface.
AsyncTask will be re-executed as background thread again, and previous background thread processing was just be redundant and zombie. AsyncTaskLoader will be just re-used basing on Loader ID that registered in Loader Manager before, so avoid re-executing network transaction.
What you're missing is that classes like AsyncTask
and LoaderManager
were written with Android in mind. Meaning, the OS is designed to make the most of minimal hardware when compared to a desktop computer. AsyncTask
limits your thread pool because you have much stricter thread limitations than on other systems. If you try to spawn 100+ threads, new threads will be rejected or crash the system. You can certainly use Thread
and Handler
, but you're on your own as far as managing it.
Last I heard, AsyncTask
supports 10 threads with a queue depth of 10 tasks (it may have increased in later versions). If this is restrictive, you can always grab the source and write your own. I've done it before. The important thing you want to consider is, can I run into trouble down the road with spawning too many threads, and if so, how am I going to handle it.
To address your question as to why it's recommended to use LoaderManager
and AsyncTaskLoader
, it's just a convenience. It's an easy way to reload data and get it to the parts of your code that depend on that data. It's not warranted in every situation.
Handler
, Threads
, and Messages
are low-level classes. This gives you flexibility -- you can combine them as you see fit to solve your particular problem. However, you also need to take care of a lot of low-level stuff as well: stopping/starting threads, routing to the correct thread, saving/restoring or re-creating instance when activities are re-created, etc.
Loaders take care of most of this for you and are designed to solve one particular problem well -- loading data in an activity. The biggest plus is that the Activity
(or FragmentActivity
) will take care of managing and restarting your loaders when the activity is re-created (which is quite tricky to do right without leaking). It also caches data so you don't need to do this yourself. That said, if you want to do something slightly different, using Loaders might get awkward. So if need more flexibility, consider AsyncTask
. If that doesn't fit, go one level lower and use Threads
and Handler
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With