Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use AsyncTaskLoader with LoaderManager, instead of simple Handler?

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:

  • Should work reliably
  • Code readability
  • Activity or Fragment should be kept clean of as much of thread management as possible

Here is the summary of my impressions (which may be wrong and some are just opinions) about the various methods:

AsyncTask

I was using simple AsyncTask without LoaderManager when I first jumped into Android:

  • Had intermittent issues, I wrote my own AsyncTaskManager to manage them with the activity life cycle.
  • There are some limitations to number of tasks and memory leaks have been reported before.
  • Biggest issue with these was that they made my code extremely convoluted, and simplifying the code defeated the purpose of using them in the first place.

AsyncTaskLoader with LoaderManager

This seems to be the recommended way to do this, so I researched it a bit:

  • After reading about these a bit, it seems the main reason this method is recommended is because it manages the tasks with the 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.
  • All the task parameters seem to have to be Parcelable or Serialiazable to go into a Bundle object.

Handler, Threads, with Messages

This is the method I settled on:

  • Easy to implement, extremely customizable.
  • You get access to the thread executing the task: set priority, set thread name for debugging, set daemon, and etc.
  • Seems much more responsive than with using AsyncTasks, based on an eye test where I click a button a lot of times and watch the results and threads flash by ;) I could benchmark this.
  • To handle life cycle issues, can write a singleton class that manages messages (persists while the process is alive). Stores them when a given activity's handler is not set up, then forwards them to the activity handler if it asks for its missed messages. Meaning a task doesn't have to restart with the same parameters, which can be critical for tasks that are non-idempotent.

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.

like image 765
Emil Davtyan Avatar asked Oct 29 '12 07:10

Emil Davtyan


People also ask

Is AsyncTaskLoader deprecated?

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.

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?

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.

What is AsyncTaskLoader How do you use AsyncTaskLoader?

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.

What is AsyncTask and AsyncTaskLoader?

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.


2 Answers

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.

like image 66
Jason Robinson Avatar answered Oct 12 '22 18:10

Jason Robinson


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.

like image 29
Nikolay Elenkov Avatar answered Oct 12 '22 18:10

Nikolay Elenkov