Hello Guys!!! Hope things are well at your side.
Today the point of discussion is Android loader versus AsyncTask.
The concept of Loaders was introduced in Android 3.0 (API Level 11). It is a mechanism of loading data asynchronously for an activity or fragment. Since loaders are specifically designed to solve the issue of Async loading, one does not have to spend too much time designing Async tasks to handle all different scenarios efficiently.
Before we proceed for Android loader we have to put some light on AsyncTask it uses drawback.
AsyncTask
Before getting into the Loader concept, it’s important to have a good idea of what the AsyncTask is and what it’s used for within Android. AsyncTask was added to Android in API level 3 (Android 1.5 Cupcake) and was said to help developers manage their threads.
Right now, AsyncTask is probably the most commonly used technique on Android for background execution. It's really easy to work with and that's what developers love about it. It gives the developer an easy way to do processing on a thread that isn’t the UI thread. This keeps the UI thread focused on the UI instead of other time-intensive tasks, such as disk or server calls
But this class has a couple of downsides and we are not always aware of them.
1. Lifecycle
(a) There is quite a misunderstanding about our AsyncTask. Developers might think that when the Activity that created the AsyncTask has been destroyed, the AsyncTask will be destroyed as well. This is not the case. The AsyncTask keeps on running, doing his doInBackground() method until it is done. Once this is done it will either go to the onCancelled(Result result) method if cancel(boolean) is invoked or the onPostExecute(Result result) method if the task has not been cancelled.
Suppose our AsyncTask was not cancelled before our Activity was destroyed. This could make our AsyncTask crash, because the view it wants to do something with, does not exist anymore. So we always have to make sure we cancel our task before our Activity is destroyed.
(b) Pausing an activity doesn’t pause the AsyncTask
2. Memory leaks
An AsyncTask has methods that run on the worker thread (doInBackground()) as well as methods that run on the UI ( onPostExecute()), it has took keep a reference to it's Activity as long as it's running. But if the Activity has already been destroyed, it will still keep this reference in memory. This is completely useless because the task has been cancelled anyway. So it gives memory leaks.
3. Configuration changes
Another problem is that we lose our results of the AsyncTask if our Activity has been recreated. For example when an orientation change occurs. The Activity will be destroyed and recreated, but our AsyncTask will now have an invalid reference to its Activity, so onPostExecute() will have no effect.
There is a solution for this. You can hold onto a reference to AsyncTask that lasts between configuration changes (for example using a global holder in the Application object). Activity.onRetainNonConfigurationInstance() and Fragment.setRetainedInstance(true) may also help you in this case.
Do we need AsyncTasks?
Not really. Now there is an easy way to implement background features in our app without having to write a lot of code(For Async Task). we can do it by using Loaders. They were introduced in Android 3.0 (Honeycomb) and are also available in the support library.
Now before going to use Android Loader for background process we have to look on its characteristics. Loaders have these characteristics:
Today the point of discussion is Android loader versus AsyncTask.
The concept of Loaders was introduced in Android 3.0 (API Level 11). It is a mechanism of loading data asynchronously for an activity or fragment. Since loaders are specifically designed to solve the issue of Async loading, one does not have to spend too much time designing Async tasks to handle all different scenarios efficiently.
Before we proceed for Android loader we have to put some light on AsyncTask it uses drawback.
AsyncTask
Before getting into the Loader concept, it’s important to have a good idea of what the AsyncTask is and what it’s used for within Android. AsyncTask was added to Android in API level 3 (Android 1.5 Cupcake) and was said to help developers manage their threads.
Right now, AsyncTask is probably the most commonly used technique on Android for background execution. It's really easy to work with and that's what developers love about it. It gives the developer an easy way to do processing on a thread that isn’t the UI thread. This keeps the UI thread focused on the UI instead of other time-intensive tasks, such as disk or server calls
But this class has a couple of downsides and we are not always aware of them.
1. Lifecycle
(a) There is quite a misunderstanding about our AsyncTask. Developers might think that when the Activity that created the AsyncTask has been destroyed, the AsyncTask will be destroyed as well. This is not the case. The AsyncTask keeps on running, doing his doInBackground() method until it is done. Once this is done it will either go to the onCancelled(Result result) method if cancel(boolean) is invoked or the onPostExecute(Result result) method if the task has not been cancelled.
Suppose our AsyncTask was not cancelled before our Activity was destroyed. This could make our AsyncTask crash, because the view it wants to do something with, does not exist anymore. So we always have to make sure we cancel our task before our Activity is destroyed.
(b) Pausing an activity doesn’t pause the AsyncTask
2. Memory leaks
An AsyncTask has methods that run on the worker thread (doInBackground()) as well as methods that run on the UI ( onPostExecute()), it has took keep a reference to it's Activity as long as it's running. But if the Activity has already been destroyed, it will still keep this reference in memory. This is completely useless because the task has been cancelled anyway. So it gives memory leaks.
3. Configuration changes
Another problem is that we lose our results of the AsyncTask if our Activity has been recreated. For example when an orientation change occurs. The Activity will be destroyed and recreated, but our AsyncTask will now have an invalid reference to its Activity, so onPostExecute() will have no effect.
There is a solution for this. You can hold onto a reference to AsyncTask that lasts between configuration changes (for example using a global holder in the Application object). Activity.onRetainNonConfigurationInstance() and Fragment.setRetainedInstance(true) may also help you in this case.
Do we need AsyncTasks?
Not really. Now there is an easy way to implement background features in our app without having to write a lot of code(For Async Task). we can do it by using Loaders. They were introduced in Android 3.0 (Honeycomb) and are also available in the support library.
Now before going to use Android Loader for background process we have to look on its characteristics. Loaders have these characteristics:
- Loaders are basically used to provide asynchronous loading of data for an Activity or Fragment on Non-UI thread. While the application should perform any call to a Loader from the main thread, the Loader (or subclasses of Loader) performs their work in a separate thread and delivers its results to the main thread.
- The code implementation should not derive directly from android.content.Loader class but specifically from android.content.CursorLoader class.
- The callbacks of the Loader are invoked at different stages during loading of data in an Activity or Fragment. In short, an Activity or a Fragment are required to implement Listeners to use Loaders.
- Loaders internally use AsyncTask to perform the data load. There is no performance gain when Loaders are compared to AsyncTask, provided that the AsyncTask are designed and developed properly.
- Loader, more specifically, CursorLoader queries the Content Resolver in the background thread so that the application's User Interface is not blocked and returns the loaded Cursor to the Activity or Fragment.
- CursorLoader handles the life cycle of the cursor. When using CursorLoader, the developer should never call close() on the cursor.
- Loader persist the data fetched to avoid repetitive fetch operations for simple Activity refresh event like orientation change, keyboard open etc.
- Loader monitor the source of its data and deliver new results when the content changes. It automatically reconnects to the last loader’s cursor when being recreated after a configuration change avoiding the need to re-query their data. In other words, CursorLoader auto updates and hence there is no need to requery the cursor.
- Loaders, in particular CursorLoader, are expected to retain their data after being stopped. This allows applications to keep their data across the Activity or fragment's onStop() and onStart() methods, so that when users return to an application, they don't have to wait for the data to reload.
- Loaders are available as a part of the compatibility library. So developers can use it in applications that run on android build previous to HoneyComb.
- Developers should use CursorLoader instead of Activity.managedQuery or Activity.startManagingCursor starting in android 3.0.
- There is only one LoaderManager per Activity or Fragment. The LoaderManager manages the life of one or more Loader instances automatically within an Activity or Fragment.
Point No 7, 8, and 9 are important. It gives Android Loader an edge over AsyncTask. Over all properties of Android Loader shows that it is useful to use Loaders in place of AsyncTask generally. In some case we can use Async task based upon our need but I will suggest you that before using Async task or Android Loader analyse your application needs. If there is no to much data to fetch from Server or DB which going to change frequently then use AsyncTask otherwise use Android Loader.
In my next post I shall discuss Android Loaders it type and uses with examples.
Thanks
Happy Coding !!!
In my next post I shall discuss Android Loaders it type and uses with examples.
Thanks
Happy Coding !!!
Good post on Async task vs Android loader
ReplyDeleteVery good post.
ReplyDeleteNice post.
ReplyDeleteIn my next post I shall discuss Android Loaders it type and uses with examples. Did you do that ?
Saurabh,
ReplyDeletevery useful post, in process of switching to curserloader in our app. One question - you didn't clarify if loader also will suffer from memory leaks. If so, what are best ways to minimize memory leaks with loaders.
Given so much info in it, These type of articles keeps the users interest in the website, and keep on sharing more .Android Training in chennai
ReplyDeletePerfect explanation about Android loader versus AsyncTask.its very useful. best Android Training in chennai |Android Training
ReplyDeleteVery useful information that you have shared and it is very useful to me.Thanks for sharing the information with us.
ReplyDeletemobile app development company in chennai
Thank you for providing such an awesome article and it is very useful blog for others to read.
ReplyDeleteAndroid Training in Delhi