January 18, 2021
Hot Topics:

How to Load Data Asynchronously in Android Apps Using Loaders

  • By Vipul Patel
  • Send Email »
  • More Articles »

Introduction To Loading Data Asynchronously in Android

Loaders are an Android construct that make it easy to load data in an activity or a fragment in an asynchronous manner.

Loaders can be bound to a data source and, when content changes in the data source, they can deliver refreshed results. Additionally, they keep the cursor context of a connection and, when they reconnect, they do not need to re-query the data.

Basics of Android Loaders

Each Activity or Fragment can have at most one LoaderManager class that is used to manage Loaders' instances. Typically, to use loaders in an Android application, we need the following:

  • Activity or Fragment class
  • Instance of LoaderManager
  • CursorLoader class to load data
  • Widget to display loader's data
  • Data source

Hands On with Android Loaders

Let's create a simple Android application that demonstrates working with Loaders.

Fire up Android Studio and Start a new Android Studio Project.

Figure 1: Opening Android Studio

Provide LoaderDemo as the Application Name and click Next.

Figure 2: Naming the Application

On the next screen, leave the default values and click Next.

Figure 3: Leaving the default values in place

On the "Add an activity to Mobile" page, choose "Blank Activity". This creates an application with a single activity.

Figure 4: Adding a Blank Activity

We then are prompted to customize the activity. We will leave the default values unchanged.

Figure 5: Again, leaving the default values in place

Click Finish to create the project files.

First, we declare the capability to read contacts in an application manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.vipul.loaderdemo" >
   <uses-permission android:name="android.permission.READ_CONTACTS" />
      android:theme="@style/AppTheme" >
         android:label="@string/app_name" >
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />

We then update the layout file to add a listview.

<RelativeLayout xmlns:android=

      android:layout_marginTop="122dp" />

Open MainActivity.java and include a few imports.

import android.app.ListActivity;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.app.LoaderManager.LoaderCallbacks;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

Next, we update the class declaration to extend LoaderCallbacks.

public class MainActivity
   extends ListActivity
   implements LoaderCallbacks<Cursor> {

We then add a few member variables.

CursorLoader myCursorLoader;
String currentFilter;
SimpleCursorAdapter myDisplayAdapter;
ListView yourListView = getListView();

   new String[]{

Next, we update the default code in the onCreate method to intiialize the loadermanager:

protected void onCreate(Bundle savedInstanceState) {
   yourListView = getListView();

   myDisplayAdapter = new SimpleCursorAdapter(this,
      android.R.layout.simple_list_item_1, null,
      new String[] { Contacts.DISPLAY_NAME},
      new int[] { android.R.id.text1}, 0);

   getLoaderManager().initLoader(0, null, this);

Lastly, we implement the callback methods for the loader.

// This method is called when initLoader is invoked.
// In this method, we create the CursorLoader
public Loader<Cursor> onCreateLoader(int id, Bundle args) {

   // Create a cursor
   // uri: The URI for the content to retrieve.
   // projection: A list of which columns to return.
   // Passing null will return all columns,
   // which is inefficient.
   // selection: A filter declaring which rows to return,
   // formatted as an SQL WHERE clause (excluding the WHERE itself).
   // Passing null will return all rows for the given URI.
   // selectionArgs: You may include ?s in the selection,
   // which will be replaced by the values from selectionArgs,
   // in the order that they appear in the selection.
   // The values will be bound as Strings.
   // sortOrder: How to order the rows, formatted as an SQL ORDER BY
   // clause (excluding the ORDER BY itself). Passing null will use
   // the default sort order, which may be unordered.

   Uri baseUri;
   if (currentFilter != null) {
      baseUri = Uri.withAppendedPath
   } else {
      baseUri = ContactsContract.Contacts.CONTENT_FILTER_URI;

   String select = "((" + Contacts.DISPLAY_NAME
      + " NOTNULL) AND ("
      + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
      + Contacts.DISPLAY_NAME + " != '' ))";
   myCursorLoader = new CursorLoader(this,
      baseUri,CONTACTS_SUMMARY_PROJECTION, select, null,
      Contacts.DISPLAY_NAME + " ASC");

   return myCursorLoader;

On the onLoadFinished callback, we swap the cursor with the data.

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

In the onLoaderReset callback, we set the swap to null.

public void onLoaderReset(Loader<Cursor> loader) {

Our application is now complete. When you run it, you will see the loaders in action.


In this article, we learned how to use loaders to get data loaded asynchronously in Android Applications. I hope you have found this information useful.


About the Author

Vipul Patel is a technology geek based in Seattle. He can be reached at vipul.patel@hotmail.com. You can visit his LinkedIn profile at https://www.linkedin.com/pub/vipul-patel/6/675/508.

This article was originally published on January 6, 2016

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date