Android Loader Detailed Explanation

Android Loader Detailed Explanation

1. Basic method of Android loader

Loaders were introduced in Android 3.0. They make it easy to asynchronously load data in an activity or fragment. Loaders have the following features:

  • They are available for every Activity and Fragment.
  • They provide the ability to load data asynchronously.
  • They monitor data sources for activity and deliver new results when the contents change.
  • When recreated due to a configuration change, they automatically reconnect to the previous loader's cursor, so there is no need to requery the data.

Loader API Overview

When using loaders, many classes and interfaces are involved. We summarize them in the following table:

Class/Interface

illustrate

LoaderManager An abstract class that is associated with an Activity or Fragment and manages one or more loader instances. This helps an application manage long-running operations that are related to the life cycle of an Activity or Fragment. The most common way is to use it with a CursorLoader, but applications are free to write their own loaders to load other types of data.

Each activity or fragment has only one LoaderManager. But a LoaderManager can have multiple loaders. LoaderManager.LoaderCallbacks is a callback interface for clients to interact with LoaderManager. For example, you use the callback method onCreateLoader() to create a new loader.

Loader

An abstract class that performs asynchronous data loading. It is the base class for loaders. You can use the typical CursorLoader, but you can also implement your own subclasses. Once loaders are activated, they will monitor their data sources and send new results when the data changes. AsyncTaskLoader provides an abstract class that provides an AsyncTask to perform asynchronous loading work. A subclass of CursorLoaderAsyncTaskLoader that queries a ContentResolver and then returns a Cursor. This class implements the loader protocol in a standard way for querying a cursor. Its cursor query is performed in a background thread through AsyncTaskLoader so that it does not block the interface. Using this loader is the best way to load data asynchronously from a ContentProvider. In contrast, performing a managed query through the fragment or activity API will not work.

2. Start a loader

LoaderManager manages one or more loaders in an Activity or Fragment. But each activity or fragment has only one LoaderManager.

You usually initialize a loader in the onCreate() method of your activity or in the onActivityCreated() method of your fragment. You can create one as follows:

  1. // Prepare the loader. You can reconnect to an existing one or start a new one.
  2. getLoaderManager().initLoader(0, null , this);

The initLoader() method has the following parameters:

  • A unique ID to identify the loader. In this example, the ID is 0.
  • Optional parameter used when initializing the loader (null in this case).
  • An implementation of LoaderManager.LoaderCallbacks. Called by the LoaderManager to report loader events. In this case, the class implements this interface, so it is passed itself: this.initLoader() ensures that a loader is initialized and activated. It has two possible results:
  • If a loader pointed to by ID already exists, then that loader will be reused.
  • If the loader does not exist, initLoader() triggers the onCreateLoader() method of LoaderManager.LoaderCallbacks. This is where you instantiate and return a new loader.

In both cases, the implementation of the passed LoaderManager.LoaderCallbacks is bound to the loader and will be called when the loader state changes. If the caller is in the starting state when calling this method, and the requested loader already exists and has generated data, the system will call onLoadFinished() immediately (that is, while initLoader() is still executing). So you must be prepared for this situation to happen.

Note that initLoader() returns the created loader, but you do not need to keep a reference to it. The LoaderManager automatically manages the life of the loader. The LoaderManager starts and stops loading operations when necessary, and maintains the state of the loader and its associated content. This means that you rarely interact with the loader directly. You usually use the methods of LoaderManager.LoaderCallbacks to intervene in the data loading process when certain events occur.

3. Restart the loader

When you use initLoader(), if a loader with the specified ID already exists, it uses that loader. If not, it creates a new one. But sometimes you want to discard the old one and start with a new one.

To discard old data, you should use restartLoader(). For example, the following implementation of SearchView.OnQueryTextListener restarts the loader when the user's query changes. The loader then needs to be restarted so that a new query can be made using the new search filter.

  1. public boolean onQueryTextChanged(String newText) {
  2. // Called when the search string in the action bar changes.
  3. // Update the search filter, then restart the load to use this new filter for new queries.
  4. mCurFilter = !TextUtils.isEmpty(newText) ? newText : null ;
  5. getLoaderManager().restartLoader(0, null , this);
  6. return   true ;
  7. }
  8. LoaderManager.LoaderCallbacks is a callback interface that allows clients to interact with LoaderManager.
  9. Loaders, usually CursorLoader, we want to keep data after it stops. This allows applications to keep data between onStop() and onStart() of an activity or fragment, so when the user returns to an application, they don't have to wait for data to load. You use the methods of LoaderManager.LoaderCallbacks to create new loaders when needed and tell the application when to stop using the loader's data.
  10. LoaderManager.LoaderCallbacks contains the following methods:
  11. onCreateLoader() —Initializes and returns a new loader based on the passed ID.
  12. onLoadFinished() —Called when a loader has completed its loading process.
  13. onLoaderReset() —Called when a loader is reset and its data is invalid.
  14.  
  15. When you try to operate a loader (for example, through initLoader()), it checks whether a loader with the specified ID already exists. If it does not exist, the LoaderManager.LoaderCallbacks method onCreateLoader() is triggered. This is where you create a new loader. Usually this loader is a CursorLoader, but you can also implement your own loader.

  1. String mCurFilter;
  2. ...
  3. public Loader< Cursor > onCreateLoader( int id, Bundle args) {
  4. // This is called when a new loader needs to be created.
  5. // We simply have a loader, so we don't need to worry about the ID.
  6. // First , pick the base URI to use depending on whether we are
  7. // currently filtering.
  8. Uri baseUri;
  9. if (mCurFilter != null ) {
  10. baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
  11. Uri.encode(mCurFilter));
  12. } else {
  13. baseUri = Contacts.CONTENT_URI;
  14. }
  15. // Now create   and   return a CursorLoader that will take care of  
  16. // creating a Cursor   for the data being displayed.
  17. String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("  
  18. + Contacts.HAS_PHONE_NUMBER + "=1) AND ("  
  19. + Contacts.DISPLAY_NAME + " != '' ))" ;
  20. return new CursorLoader(getActivity(), baseUri,
  21. CONTACTS_SUMMARY_PROJECTION, select , null ,
  22. Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC" );
  23. }

<<:  Play with Android nested scrolling

>>:  Android background killing series 2: ActivityManagerService and App on-site recovery mechanism

Recommend

How to clean and disinfect your home? Save!

How to disinfect correctly after picking up a pac...

The little-known secrets of bananas

I think when you see the title, you will probably...

Top Ten World-West Traffic Tunnels in China

1 The world's longest twin-hole highway tunne...

What is the technology behind the popular AI painting? (Part 2)

In the previous issue, we introduced the GAN mode...

How to advertise on public accounts? Case Analysis

The number of advertisements placed on official a...

Featured recommendation: Detailed explanation of the use of xUtils framework

Introduction to xUtils xUtils was originally deri...

Cisco: Digital transformation of the oil and gas industry is underway

199IT original compilation When it comes to energ...

The smell you love so much can actually promote nerve regeneration?

Compiled by: Gong Zixin Known for its rich, earth...

Summary of content community product operation methodology

Content operation refers to the complete operatio...

If the Netherlands wins the World Cup: Free space tour for everyone

The Dutch national team is now one of the top four...

Did science stagnate after Einstein?

There is often such a question on the Internet, w...