public
abstract
class
LoaderManager
extends Object
java.lang.Object | |
↳ | android.app.LoaderManager |
Interface associated with an Activity
or Fragment
for managing
one or more Loader
instances associated with it. This
helps an application manage longer-running operations in conjunction with the
Activity or Fragment lifecycle; the most common use of this is with a
CursorLoader
, however applications are free to write
their own loaders for loading other types of data.
While the LoaderManager API was introduced in
HONEYCOMB
, a version of the API
at is also available for use on older platforms through
FragmentActivity
. See the blog post
Fragments For All for more details.
As an example, here is the full implementation of a Fragment
that displays a ListView
containing the results of
a query against the contacts content provider. It uses a
CursorLoader
to manage the query on the provider.
public static class CursorLoaderListFragment extends ListFragment implements OnQueryTextListener, OnCloseListener, LoaderManager.LoaderCallbacks<Cursor> { // This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; // The SearchView for doing filtering. SearchView mSearchView; // If non-null, this is the current filter the user has provided. String mCurFilter; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Give some text to display if there is no data. In a real // application this would come from a resource. setEmptyText("No phone numbers"); // We have a menu item to show in action bar. setHasOptionsMenu(true); // Create an empty adapter we will use to display the loaded data. mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_2, null, new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, new int[] { android.R.id.text1, android.R.id.text2 }, 0); setListAdapter(mAdapter); // Start out with a progress indicator. setListShown(false); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this); } public static class MySearchView extends SearchView { public MySearchView(Context context) { super(context); } // The normal SearchView doesn't clear its search text when // collapsed, so we will do this for it. @Override public void onActionViewCollapsed() { setQuery("", false); super.onActionViewCollapsed(); } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Place an action bar item for searching. MenuItem item = menu.add("Search"); item.setIcon(android.R.drawable.ic_menu_search); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); mSearchView = new MySearchView(getActivity()); mSearchView.setOnQueryTextListener(this); mSearchView.setOnCloseListener(this); mSearchView.setIconifiedByDefault(true); item.setActionView(mSearchView); } public boolean onQueryTextChange(String newText) { // Called when the action bar search text has changed. Update // the search filter, and restart the loader to do a new query // with this filter. String newFilter = !TextUtils.isEmpty(newText) ? newText : null; // Don't do anything if the filter hasn't actually changed. // Prevents restarting the loader when restoring state. if (mCurFilter == null && newFilter == null) { return true; } if (mCurFilter != null && mCurFilter.equals(newFilter)) { return true; } mCurFilter = newFilter; getLoaderManager().restartLoader(0, null, this); return true; } @Override public boolean onQueryTextSubmit(String query) { // Don't care about this. return true; } @Override public boolean onClose() { if (!TextUtils.isEmpty(mSearchView.getQuery())) { mSearchView.setQuery(null, true); } return true; } @Override public void onListItemClick(ListView l, View v, int position, long id) { // Insert desired behavior here. Log.i("FragmentComplexList", "Item clicked: " + id); } // These are the Contacts rows that we will retrieve. static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS, Contacts.CONTACT_PRESENCE, Contacts.PHOTO_ID, Contacts.LOOKUP_KEY, }; public Loader<Cursor> onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. // First, pick the base URI to use depending on whether we are // currently filtering. Uri baseUri; if (mCurFilter != null) { baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(mCurFilter)); } else { baseUri = Contacts.CONTENT_URI; } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + Contacts.DISPLAY_NAME + " != '' ))"; return new CursorLoader(getActivity(), baseUri, CONTACTS_SUMMARY_PROJECTION, select, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); } public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); // The list should now be shown. if (isResumed()) { setListShown(true); } else { setListShownNoAnimation(true); } } public void onLoaderReset(Loader<Cursor> loader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); } }
For more information about using loaders, read the Loaders developer guide.
Nested classes | |
---|---|
interface |
LoaderManager.LoaderCallbacks<D>
Callback interface for a client to interact with the manager. |
Public constructors | |
---|---|
LoaderManager()
|
Public methods | |
---|---|
abstract
void
|
destroyLoader(int id)
Stops and removes the loader with the given ID. |
abstract
void
|
dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)
Print the LoaderManager's state into the given stream. |
static
void
|
enableDebugLogging(boolean enabled)
Control whether the framework's internal loader manager debugging logs are turned on. |
abstract
<D>
Loader<D>
|
getLoader(int id)
Return the Loader with the given id or null if no matching Loader is found. |
abstract
<D>
Loader<D>
|
initLoader(int id, Bundle args, LoaderCallbacks<D> callback)
Ensures a loader is initialized and active. |
abstract
<D>
Loader<D>
|
restartLoader(int id, Bundle args, LoaderCallbacks<D> callback)
Starts a new or restarts an existing |
Inherited methods | |
---|---|
From
class
java.lang.Object
|
void destroyLoader (int id)
Stops and removes the loader with the given ID. If this loader
had previously reported data to the client through
onLoadFinished(Loader, Object)
, a call
will be made to onLoaderReset(Loader)
.
Parameters | |
---|---|
id |
int
|
void dump (String prefix, FileDescriptor fd, PrintWriter writer, String[] args)
Print the LoaderManager's state into the given stream.
Parameters | |
---|---|
prefix |
String :
Text to print at the front of each line. |
fd |
FileDescriptor :
The raw file descriptor that the dump is being sent to. |
writer |
PrintWriter :
A PrintWriter to which the dump is to be set. |
args |
String :
Additional arguments to the dump request.
|
void enableDebugLogging (boolean enabled)
Control whether the framework's internal loader manager debugging logs are turned on. If enabled, you will see output in logcat as the framework performs loader operations.
Parameters | |
---|---|
enabled |
boolean
|
Loader<D> getLoader (int id)
Return the Loader with the given id or null if no matching Loader is found.
Parameters | |
---|---|
id |
int
|
Returns | |
---|---|
Loader<D> |
Loader<D> initLoader (int id, Bundle args, LoaderCallbacks<D> callback)
Ensures a loader is initialized and active. If the loader doesn't already exist, one is created and (if the activity/fragment is currently started) starts the loader. Otherwise the last created loader is re-used.
In either case, the given callback is associated with the loader, and
will be called as the loader state changes. If at the point of call
the caller is in its started state, and the requested loader
already exists and has generated its data, then
callback onLoadFinished(Loader
will
be called immediately (inside of this function), so you must be prepared
for this to happen.
Parameters | |
---|---|
id |
int :
A unique identifier for this loader. Can be whatever you want.
Identifiers are scoped to a particular LoaderManager instance. |
args |
Bundle :
Optional arguments to supply to the loader at construction.
If a loader already exists (a new one does not need to be created), this
parameter will be ignored and the last arguments continue to be used. |
callback |
LoaderCallbacks :
Interface the LoaderManager will call to report about
changes in the state of the loader. Required.
|
Returns | |
---|---|
Loader<D> |
Loader<D> restartLoader (int id, Bundle args, LoaderCallbacks<D> callback)
Starts a new or restarts an existing Loader
in
this manager, registers the callbacks to it,
and (if the activity/fragment is currently started) starts loading it.
If a loader with the same id has previously been
started it will automatically be destroyed when the new loader completes
its work. The callback will be delivered before the old loader
is destroyed.
Parameters | |
---|---|
id |
int :
A unique identifier for this loader. Can be whatever you want.
Identifiers are scoped to a particular LoaderManager instance. |
args |
Bundle :
Optional arguments to supply to the loader at construction. |
callback |
LoaderCallbacks :
Interface the LoaderManager will call to report about
changes in the state of the loader. Required.
|
Returns | |
---|---|
Loader<D> |