The concurrency constructs we've encountered so far have been quite general in purpose, but in this chapter we'll take a look at a construct with a more specific focus—Loader
.
In this chapter we will cover the following topics:
AsyncTaskLoader
CursorLoader
As the name suggests, the job of Loader
is to load data on behalf of other parts of the application, and to make that data available across activities and fragments within the same process.
Loaders were introduced to the Android platform at API level 11, but are available for backwards compatibility through the support libraries. The examples in this chapter use the support library to target API levels 7 through 19.
Provided we implement our Loaders correctly, we get a number of benefits:
Loader
instance is destroyed, and allows Loaders to live outside the Activity
lifecycle, making their data available across the application and across Activity
restarts.When we use Loaders, we will not do so in isolation, because they form part of a small framework. Loaders are managed objects, and are looked after by a LoaderManager
, which takes care of coordinating Loader
lifecycle events with the Fragment
and Activity
lifecycles, and makes the Loader
instances available to client code throughout an application.
To connect a Loader
with a recipient for the data it loads, the framework provides the LoaderCallbacks
interface. LoaderCallbacks
requires an implementing class to provide three methods:
CursorLoader onCreateLoader(int id, Bundle bundle); void onLoadFinished(Loader<Cursor> loader, Cursor media); void onLoaderReset(Loader<Cursor> loader);
The onCreateLoader
method allows us to instantiate the particular Loader
implementation we want. The onLoaderFinished
method provides a way to receive the result of background loading in the main thread. The onLoaderReset
method gives us a place to perform any cleanup that is needed when Loader
is being discarded.
Loader
is an abstract class, and does not itself implement any asynchronous behavior. Although we can extend Loader
directly, it is more common to use one of the two provided subclasses, AsyncTaskLoader
or CursorLoader
, depending on our requirements.
AsyncTaskLoader
is a general-purpose Loader
, which we can subclass when we want to load just about any kind of data from just about any kind of source, and do so off the main thread.
CursorLoader
extends AsyncTaskLoader
, specializing it to efficiently source data from a local database and manage the associated database Cursor
correctly.
Let's begin by implementing a simple AsyncTaskLoader
to load a bitmap
in the background from the MediaStore.
18.119.118.210