What's defference between AsyncTaskLoader and Loader? - android

Cannot understand when I need to use Loader and when AsyncTaskLoader? I read docs by these class but I understood it badly. As I understood Loader allows to do a background work so it must be launched in non-GUI thread, it isn't? Why does AsyncTaskLoader do all same? I'm confused already.
Please, someone explain me more details.

All of the Loader methods are called on the main thread - Loader does not do any work on a background thread. This allows you to use whatever loading mechanism you want - be it a separate thread, callbacks to another component, or anything else.
AsyncTaskLoader extends Loader and adds loadInBackground(), a method specifically called on a background thread. It is simply a convenience class for the simple case.
In either case, the real role of Loaders is to make loading data lifecycle aware as explained in this blog post - Loaders (and hence, AsyncTaskLoaders) survive configuration changes such as screen rotations. The blog contains a number of examples of AsyncTaskLoader, using an AsyncTaskLoader with an observer of changes, and a Loader which gets data from another data source using callbacks.

Related

Is there any scenario where using AsyncTask is better than AsyncTaskLoader?

I am currently studying about Loaders and about how they could overcome changes such as screen orientation during application lifecycle, and so far, from what I have read, AsyncTaskLoader does the same job as AsyncTask and even better. Therefore, should not AsyncTask be considered obsolete or does it provide the developers with some hidden advantages?
I am currently studying about Loaders and about how they could overcome changes such as screen orientation during application lifecycle
The Architecture Components' support for view-models and LiveData is Google's current direction for addressing the problems that loaders tried to address.
AsyncTaskLoader does the same job as AsyncTask and even better
Note that AsyncTaskLoader uses an AsyncTask.
should not AsyncTask be considered obsolete
Yes, insofar as we have other patterns and libraries to use (e.g., RxJava, LiveData). That being said, AsyncTask, used correctly, is an OK option. The challenge is in using it correctly (e.g., from a retained fragment, with care to avoid interacting with the hosting activity on a background thread).
does it provide the developers with some hidden advantages?
Your argument seems to be "an ocean liner has more features than does a rowboat, so shouldn't we consider rowboats to be obsolete?". Ocean liners have their costs, and ocean liners cannot do everything that a rowboat can (e.g., travel in shallow water, be towed behind a truck).
Loaders were designed — to the extent that they ever had a "design" — to:
load data in the background, typically via an AsyncTask
retain that data across configuration changes
automatically deliver updates when the requested data happens to change
Not everything needs that. For example, the loader pattern targets read operations (where we actually "load" data), but it does not really help with write operations (where we are changing the data). Yet we still want to do write operations asynchronously and find out about the results even if we undergo a configuration change. You can squeeze write operations into loaders, but it is not a natural fit. Using an AsyncTask or something else, instead of a loader, would be more natural.
Think this way,
The AsyncTaskLoader can be used at any place where the AsyncTask is.
The main advantage is the ability to persist between the lifecycles.
If you use an AsyncTask and call a Network Operations to get some data from the Internet and the User rotates the phone, your AsyncTask will have to start the task again to grab the data, and this could be potentially dangerous to your application because you could have a memory leak.
So, in any case, Loaders are an evolution of the AsyncTask, they are basically improved AsyncTasks.
I believe that the AsyncTask is still alive because when you are performing some simple task in the Background Thread you can do this more simply using an AsyncTask with an anonymous inner class, and deliver the results right away to the UI Thread.

Android - SQLite ContentResolver insert/delete/update on UI Thread?

I have looked through many examples/tutorials of using SQLite in Android. Let's say you have an app that uses SQLite, ContentProvider, CursorLoader, a custom CursorAdapter.
Now all major examples of this that I've found rely on a CursorLoader to fetch data to the CursorAdapter, which by the nature of CursorLoader happens in an Async - UI thread safe manner. However, these same examples all make insert/delete/update calls through the ContentResolver on the main thread (e.g. from onClick, onResume, onPause). (Example) They don't wrap these calls in an AsyncTask or launch a separate thread or use the AsyncQueryHandler.
Why is this, how can so many well written blogs/examples make such an obvious mistake? Or are simple single row insert/delete/update calls so quick that they are safe enough to launch from the Main/UI thread? What is the proper way to do these quick calls?
I also got confused about the samples making calls on the main thread. I guess the samples just simplified the demonstrations avoiding extra threads and callbacks, since single insert/update/delete call may return quickly.
Besides the Loader pattern for query, android did provide a helper class AsyncQueryHandler, since API level 1, for async CRUD operations with full CRUD callbacks supported. The AsyncQueryHandler works inside with a HandlerThread for the async operations and delivers the results back to the main thread.
So I do believe the ContentProvider queries should run in worker threads other than the UI, and those samples may not be best practices according to the official design.
=== edit
Found an annotation from the official framework docs, see this or this, Line 255:
In practice, this should be done in an asynchronous thread instead of
on the main thread. For more discussion, see Loaders. If you are not
just reading data but modifying it, see {#link android.content.AsyncQueryHandler}.
=== edit 2
Link to actual android dev guide containing the above quote
This question has been on my mind since a long time. I guess, this depends on the complexity of the file we are trying to Insert, Update or Delete. If our application is going to Insert or Update large files, it would be always right to do it asynchronously and if the files aren't going to be that big, running it on UI thread can be done.
However, it is always recommended to continue with Database operations on a separate thread.
I think you've answered your own question. I do believe CursorLoader extends AsyncTaskLoader. Calls made from UI thread only process the call TO the CusorLoader (which uses AsyncTask.) What is being done BY the call still does not occur on UI Thread. Making a call to a method/function that then runs things on a seperate thread is still doing work away from UI thread.
What work do you think is happening on the UI thread?
Please show Debug log if possible or example where you think work is done on UI.
It shouldn't be.
Not trying to argue just want to know how you've come to the conclusion of UI work?

Guideline to choose among AsyncTaskLoader and AsyncTask to be used in Fragment

Look at LoaderCustomSupport (Use AsyncTaskLoader) and FragmentRetainInstanceSupport (Use Thread, almost equivalent to AsyncTask)
Both examples have the following similarities.
Both do not block UI thread when loading data
The data fetching thread is not destroyed when user performs configuration change like screen rotation.
When data fetching thread finished fetching data, it can update to the correct Fragment UI
However, there are differences.
AsyncTaskLoader
Seems like there is no easy way to update intermediate progress to a progress bar dialog
AsyncTask
Not sure on this. But Android documentation seems to recommend AsyncTaskLoader for async data loading and updating final result to UI?
Is there any guideline, or checklist to look at, to make a decision on whether to choose AsyncTaskLoader or AsyncTask, to do a time-consuming loading task and update the result to Fragment's UI?
your question made me interested and tried sometimes to look into the differences. Here i am writing my observations.
For the premature termination the asynchronous task using AsyncTask will continue running in its thread. The processing of the results can soon lead to unrequested results while AsyncTaskLoader handle the premature termination of the activity
AsyncTaskLoader handles activity configuration changes (IE when the user rotates the screen).
AsyncTaskLoader is intended load data for DataAdapters so for this purpose it is best to use AsyncTaskLoader But if you need to change UI (specially fragments) after task completion it is better to use AsyncTask as you can't change fragments in onLoadFinished of AsynTaskLoader.
So to me the usage depends on your task. and if the above 3 points doesnt bother you then the performance is same ( haven't found any documents though , but in this case asynctaskloader is recommended :S)
some related links
AsyncTaskLoader vs AsyncTask
http://andreas-kluck.blogspot.com/2012/02/asynctask-and-asynctaskloader.html
AsyncTaskLoaders, like all Loaders, are intended to solve the rotation problem, which is when an AsyncTask is created on an Activity, then the device is rotated before the task has completed that AsyncTask will be lost with the destruction of the Activity.
It's true that all Loaders currently don't support publishing progress, so if this is a requirement for your situation then you should consider an alternative. If rotation, or any other event that causes the Activity to be destroyed, isn't an issue then just use an AsyncTask, otherwise you might want to use a Service, and register a binder to push progress messages back and forth.
Service and Binder messages are kind of a pain though, in my opinion. I find a much easier solution is to use LocalBroadcastManager to send progress broadcasts from an IntentService (or AsyncTaskLoader) and have a BroadcastReceiver in the Activity receive the broadcast and display the progress.

Android Async Data Loading Methods

If I need to asynchronously load some data via HTTP (or whatever) in order to update the UI, I have a few options when writing an Android application (among many others that I'm sure I missed):
Use a regular thread and a handler to update the UI.
AsyncTask
Use and IntentService, and use either a callback or broadcast the results via an Intent.
Using Loaders.
From what I understand, an IntentService is not tied to an Activity's lifecycle, so any changes to orientation, etc, will not impact the retrieval of data. Where this is not the case for an AsyncTask or thread fired off within an Activity.
The reason for the question, is that I just recently read about Loaders, and am confused as to their application. They seem to be more closely tied to a data source, where if the data source changes, then "transparently" everything is handled appropriately. Loaders also appear to be tolerant to configuration/orientation changes (I believe).
I've been currently using an IntentService to make RESTful service calls, and broadcasting the results to be received by appropriate Activities.
I'm assuming I could write an HTTP based Loader, but I'm not sure if this is the best use of this mechanism.
What are the advantages/disadvantages to using one of the async data loading methods over any other?
All of these mechanisms are simply options. There's no such thing as a one size fits all tool and so all of these different methods of completing the same task is a way to cover as many use cases as possible.
Ultimately, it's up to you to decide which method makes more sense for your scenario. But for a sort of generic explanation of what you should use...
Regular thread and a handler - Why when there are other, simpler, options?
AsyncTask - Since an AsyncTask will almost always depend on an Activity, use this when you need to load data asynchronously and you are 100% certain of how long it may take. Example: Executing an SQLite query.
IntentService/Service - Services are not bound to an Activity like an AsyncTask is, therefore, they are perfect for scenarios in which you may not know how long it will take to complete. Example: Downloading data from a web API and updating a database.
Loaders - Loaders are aimed at simplifying the process of loading data and populating it into UI. The nature of Loaders sort of assumes that the data you will be loading will be presented to the user as a list of some sort. Example: Downloading data and populating it into a ListView

AsyncTaskLoader vs AsyncTask

Since Honeycomb and the v4 Compatibility Library it is possible to use AsyncTaskLoader. From what I understand, the AsyncTaskLoader can survive through config changes like screen flips.
Is it recommended to use AsyncTaskLoader instead of AsyncTask? Does LoaderManager get in the picture too?
But I haven't found any good example(s) about how to correctly use the AsyncTaskLoader. The docs also provide no examples. Can anyone provide some good examples.
You can have a look at the compatibility library's source code to get more info. What a FragmentActivity does is:
keep a list of LoaderManager's
make sure they don't get destroyed when you flip your phone (or another configuration change occurs) by saving instances using onRetainNonConfigurationInstance()
kick the right loader when you call initLoader() in your Activity
You need to use the LoaderManager to interface with the loaders, and provide the needed callbacks to create your loader(s) and populate your views with the data they return.
Generally it should be easier than managing AsyncTask's yourself. However, AsyncTaskLoader is not exactly well documented, so you should study the example in the docs and/or model your code after CursorLoader.
Comparing AsyncTaskLoader vs. AsyncTask, as you may know, when you rotate your device screen, it may destroy and re-create your activity. To make it clear. let's imagine rotating your device while networking transaction is going on:
AsyncTask will be re-executed as a background thread again, and the previous background thread processing will just be redundant and zombie.
AsyncTaskLoader will just be re-used basing on Loader ID that was registered in Loader Manager before, so re-executing network transaction will be avoided.
In summary, AsyncTaskLoader prevents duplication of background threads and eliminates duplication of zombie activities.
AsyncTaskLoader performs the same function as the AsyncTask, but a bit better. It can handle Activity configuration changes more easily, and it behaves within the life cycles of Fragments and Activities. The nice thing is that the AsyncTaskLoader can be used in any situation that the AsyncTask is being used. Anytime data needs to be loaded into memory for the Activity/Fragment to handle, The AsyncTaskLoader can do the job better.
There are a few issues with using AsyncTasks, though:
Configuration changes can mess things up
Pausing an activity doesn’t pause the AsyncTask
A fair amount of boilerplate code (which means more possible errors)
AsyncTaskLoader doc
Some differences other than described in other answers:
When using AsyncTaskLoader over AsyncTask:
AsyncTaskLoader gives us liberty to load old cached data until new data is returned by forceLoad()
We can set delays to AsyncTaskLoader by setUpdateThrottle() which can prevent consecutive updates to client (Activity/Fragment)
AsyncTaskLoader can be shared to multiple fragments if they have common parent activity and if it was started from getActivity().getSupportLoaderManager()
AsyncTaskLoader is destroyed by LoaderManger when its linked activity is no more available. while we need to manually destroy AsyncTasks if its caller activity destroys. This saves our time from writing all the clearing stuff. AsyncTaskLoader plays well with their respective lifecycles.
So, AsyncTaskLoader is way better than AsyncTask.

Categories

Resources