Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncTaskLoader basic example. (Android)

Tags:

I am using a Loader in my application and based on the result I get from the query I perform on COntacts using this Loader I perform some calculations and store them back in a Sqlite DB. I want this operation to be Asynchronous, however I am confused between using an Async task, as I have lot of different data types to return or should I use a simple handler or an AsyncTaskLoader, I want it to be simple as I am new to Loaders. I tried to search around for examples of AsyncTaskLoader but it seems rocket science, a basic and simple functional example of any of the three in the context of my scenario would be a lot helpful.

like image 591
Skynet Avatar asked Nov 29 '13 05:11

Skynet


People also ask

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 the difference between 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.

How do I run async tasks on Android?

To start an AsyncTask the following snippet must be present in the MainActivity class : MyTask myTask = new MyTask(); myTask. execute(); In the above snippet we've used a sample classname that extends AsyncTask and execute method is used to start the background thread.

Is AsyncTaskLoader deprecated?

This class was deprecated in API level 28.


2 Answers

If you wish to use AsyncTaskLoader, here's a nice sample for you.

EDIT: I've decided to make a simpler solution (based on this repo):

public abstract class AsyncTaskLoaderEx<T> extends AsyncTaskLoader<T> {     private static final AtomicInteger sCurrentUniqueId = new AtomicInteger(0);     private T mData;     public boolean hasResult = false;      public static int getNewUniqueLoaderId() {         return sCurrentUniqueId.getAndIncrement();     }      public AsyncTaskLoaderEx(final Context context) {         super(context);         onContentChanged();     }      @Override     protected void onStartLoading() {         if (takeContentChanged())             forceLoad();         //this part should be removed from support library 27.1.0 :         //else if (hasResult)         //    deliverResult(mData);     }      @Override     public void deliverResult(final T data) {         mData = data;         hasResult = true;         super.deliverResult(data);     }      @Override     protected void onReset() {         super.onReset();         onStopLoading();         if (hasResult) {             onReleaseResources(mData);             mData = null;             hasResult = false;         }     }      protected void onReleaseResources(T data) {         //nothing to do.     }      public T getResult() {         return mData;     } } 

Usage:

in your activity:

        getSupportLoaderManager().initLoader(TASK_ID, TASK_BUNDLE, new LoaderManager.LoaderCallbacks<Bitmap>() {             @Override             public Loader<Bitmap> onCreateLoader(final int id, final Bundle args) {                 return new ImageLoadingTask(MainActivity.this);             }              @Override             public void onLoadFinished(final Loader<Bitmap> loader, final Bitmap result) {                 if (result == null)                     return;                 //TODO use result             }              @Override             public void onLoaderReset(final Loader<Bitmap> loader) {             }         }); 

inner static class , or a normal class:

private static class ImageLoadingTask extends AsyncTaskLoaderEx<Bitmap> {      public ImageLoadingTask (Context context) {         super(context);     }      @Override     public Bitmap loadInBackground() {         //TODO load and return bitmap     } } 

Update: starting from support library 27.1.0, things changed a bit (link here) :

In version 27.1.0, onStartLoading() is called every time the Activity is started. Since you call deliverResult() in onStartLoading(), you trigger onLoadFinished(). This is Working as Intended.

You should remove your call to deliverResult() from onStartLoading() as it is not needed (Loaders already deliver results computed in loadInBackground() without any additional work needed on your part).

I've updated the code above for this change.


EDIT: Updated, kotlin version can be found here.

like image 54
android developer Avatar answered Oct 24 '22 23:10

android developer


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. But using AsyncTask you can mess up with configuration changes.

Key information: AsyncTaskLoader is subclass of Loader. This class performs the same function as the AsyncTask, but a bit better, it can also be useful in handling configuration changes (screen orientation).

A very good example and explanation is given here. http://www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html

Google has a pretty good example directly in the API Docs. Android Design Patterns provides some more detail and the reasoning behind Loaders.

This tutorial will definetly help You. http://www.javacodegeeks.com/2013/08/android-custom-loader-to-load-data-directly-from-sqlite-database.html

like image 39
DeepakPanwar Avatar answered Oct 24 '22 23:10

DeepakPanwar