| page.title=Running a Query with a CursorLoader | |
| trainingnavtop=true | |
| startpage=true | |
| @jd:body | |
| <!-- This is the training bar --> | |
| <div id="tb-wrapper"> | |
| <div id="tb"> | |
| <h2>This lesson teaches you to</h2> | |
| <ol> | |
| <li> | |
| <a href="#Extend">Define an Activity That Uses CursorLoader</a> | |
| </li> | |
| <li> | |
| <a href="#InitializeLoader">Initialize the Query</a> | |
| </li> | |
| <li> | |
| <a href="#DefineLaunch">Start the Query</a> | |
| </li> | |
| </ol> | |
| <h2>Try it out</h2> | |
| <div class="download-box"> | |
| <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a> | |
| <p class="filename">ThreadSample.zip</p> | |
| </div> | |
| </div> | |
| </div> | |
| <p> | |
| A {@link android.support.v4.content.CursorLoader} runs an asynchronous query in the background | |
| against a {@link android.content.ContentProvider}, and returns the results to the | |
| {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity} from which it | |
| was called. This allows the {@link android.app.Activity} or | |
| {@link android.support.v4.app.FragmentActivity} to continue to interact with the user while the | |
| query is ongoing. | |
| </p> | |
| <h2 id="Extend">Define an Activity That Uses CursorLoader</h2> | |
| <p> | |
| To use a {@link android.support.v4.content.CursorLoader} with an | |
| {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity}, use the | |
| {@link android.support.v4.app.LoaderManager.LoaderCallbacks LoaderCallbacks<Cursor>} | |
| interface. A {@link android.support.v4.content.CursorLoader} invokes callbacks defined | |
| in this interface to communicate with the class; this lesson and the next one | |
| describe each callback in detail. | |
| </p> | |
| <p> | |
| For example, this is how you should define a {@link android.support.v4.app.FragmentActivity} | |
| that uses the support library version of {@link android.support.v4.content.CursorLoader}. By | |
| extending {@link android.support.v4.app.FragmentActivity}, you get support for | |
| {@link android.support.v4.content.CursorLoader} as well as | |
| {@link android.support.v4.app.Fragment}: | |
| </p> | |
| <pre> | |
| public class PhotoThumbnailFragment extends FragmentActivity implements | |
| LoaderManager.LoaderCallbacks<Cursor> { | |
| ... | |
| } | |
| </pre> | |
| <h2 id="InitializeLoader">Initialize the Query</h2> | |
| <p> | |
| To initialize a query, call | |
| {@link android.support.v4.app.LoaderManager#initLoader LoaderManager.initLoader()}. This | |
| initializes the background framework. You can do this after the user has entered data that's | |
| used in the query, or, if you don't need any user data, you can do it in | |
| {@link android.support.v4.app.FragmentActivity#onCreate onCreate()} or | |
| {@link android.support.v4.app.Fragment#onCreateView onCreateView()}. For example: | |
| </p> | |
| <pre> | |
| // Identifies a particular Loader being used in this component | |
| private static final int URL_LOADER = 0; | |
| ... | |
| /* When the system is ready for the Fragment to appear, this displays | |
| * the Fragment's View | |
| */ | |
| public View onCreateView( | |
| LayoutInflater inflater, | |
| ViewGroup viewGroup, | |
| Bundle bundle) { | |
| ... | |
| /* | |
| * Initializes the CursorLoader. The URL_LOADER value is eventually passed | |
| * to onCreateLoader(). | |
| */ | |
| getLoaderManager().initLoader(URL_LOADER, null, this); | |
| ... | |
| } | |
| </pre> | |
| <p class="note"> | |
| <strong>Note:</strong> The method {@link android.support.v4.app.Fragment#getLoaderManager | |
| getLoaderManager()} is only available in the {@link android.support.v4.app.Fragment} class. To | |
| get a {@link android.support.v4.app.LoaderManager} in a | |
| {@link android.support.v4.app.FragmentActivity}, call | |
| {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager | |
| getSupportLoaderManager()}. | |
| </p> | |
| <h2 id="DefineLaunch">Start the Query</h2> | |
| <p> | |
| As soon as the background framework is initialized, it calls your implementation of | |
| {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}. | |
| To start the query, return a {@link android.support.v4.content.CursorLoader} from this method. | |
| You can instantiate an empty {@link android.support.v4.content.CursorLoader} and then use its | |
| methods to define your query, or you can instantiate the object and define the query at the | |
| same time: | |
| </p> | |
| <pre> | |
| /* | |
| * Callback that's invoked when the system has initialized the Loader and | |
| * is ready to start the query. This usually happens when initLoader() is | |
| * called. The loaderID argument contains the ID value passed to the | |
| * initLoader() call. | |
| */ | |
| @Override | |
| public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) | |
| { | |
| /* | |
| * Takes action based on the ID of the Loader that's being created | |
| */ | |
| switch (loaderID) { | |
| case URL_LOADER: | |
| // Returns a new CursorLoader | |
| return new CursorLoader( | |
| getActivity(), // Parent activity context | |
| mDataUrl, // Table to query | |
| mProjection, // Projection to return | |
| null, // No selection clause | |
| null, // No selection arguments | |
| null // Default sort order | |
| ); | |
| default: | |
| // An invalid id was passed in | |
| return null; | |
| } | |
| } | |
| </pre> | |
| <p> | |
| Once the background framework has the object, it starts the query in the background. When the | |
| query is done, the background framework calls | |
| {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}, | |
| which is described in the next lesson. | |
| </p> |