diff --git a/docs/html/training/load-data-background/define-launch-query.jd b/docs/html/training/load-data-background/define-launch-query.jd new file mode 100644 index 0000000000000..f7978f4a89840 --- /dev/null +++ b/docs/html/training/load-data-background/define-launch-query.jd @@ -0,0 +1,83 @@ +page.title=Defining and Launching the Query +trainingnavtop=true +startpage=true + +@jd:body + + +
+ To perform a query, create the {@link android.support.v4.content.CursorLoader}, set up its + query, and pass it to the loader framework. From then on, the framework manages everything. + It runs the query on a background thread, returns the results to the foreground, and + watches for changes to the data associated with the query. +
++ Pass a {@link android.support.v4.content.CursorLoader} to the loader framework in + your implementation of + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}. + The loader framework calls this method when you create a loader by calling + {@link android.support.v4.app.LoaderManager#initLoader initLoader()}. You can create + a {@link android.support.v4.content.CursorLoader} anywhere, + but the preferred way is to create it in + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}, + because this defers creation until the object is actually needed. +
+
+ Notice that {@link android.support.v4.app.LoaderManager#initLoader initLoader()} will only
+ {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+ if the {@link android.support.v4.content.CursorLoader} doesn't already exist; otherwise, it
+ re-uses the existing {@link android.support.v4.content.CursorLoader}. The loader framework
+ tracks {@link android.support.v4.content.CursorLoader} instance using the id
+ value passed to {@link android.support.v4.app.LoaderManager#initLoader initLoader()}.
+
+ To create a {@link android.support.v4.content.CursorLoader} and define its
+ query at the same time, call the constructor
+{@link android.support.v4.content.CursorLoader#CursorLoader(Context, Uri, String[], String, String[], String)
+ CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder)}. The
+ context and uri arguments are required, but the others are optional.
+ To use the default value for an optional argument, pass in null. The
+ {@link android.support.v4.content.CursorLoader} runs the query against the
+ {@link android.content.ContentProvider} identified by uri, just as if you had
+ called {@link android.content.ContentResolver#query ContentResolver.query()} with the same
+ arguments.
+
+ For example: +
+
+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:
+ /*
+ * Return a new CursorLoader
+ */
+ return new CursorLoader(
+ this, // Context
+ DataProviderContract.IMAGE_URI, // Provider's content URI
+ PROJECTION, // Columns to return
+ null, // Return all rows
+ null, // No search arguments
+ null); // Default search order
+ default:
+ // An invalid id was passed in
+ return null;
+ }
+}
+
diff --git a/docs/html/training/load-data-background/handle-results.jd b/docs/html/training/load-data-background/handle-results.jd
new file mode 100644
index 0000000000000..f8e003a3401fc
--- /dev/null
+++ b/docs/html/training/load-data-background/handle-results.jd
@@ -0,0 +1,104 @@
+page.title=Handling the Results
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+
++ {@link android.support.v4.content.CursorLoader} returns its query results to your + implementation of + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished + LoaderCallbacks.onLoadFinished()}, in the form of a {@link android.database.Cursor}. In the + callback, you can update your data display, do further processing on the + {@link android.database.Cursor} data, and so forth. +
++ When the loader framework detects changes to data associated with the query, + it resets the {@link android.support.v4.content.CursorLoader}, closes the current + {@link android.database.Cursor}, and then invokes your implementation of + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. + Use this callback to delete references to the current {@link android.database.Cursor}; when the + loader framework destroys the {@link android.database.Cursor}, you won't have outstanding + references that cause memory leaks. +
++ The following two snippets are an example of displaying the results of a query, using a + {@link android.widget.ListView} backed by a + {@link android.support.v4.widget.SimpleCursorAdapter}. +
++ The first snippet shows the {@link android.widget.ListView} and + {@link android.support.v4.widget.SimpleCursorAdapter}: +
++// Gets a handle to the Android built-in ListView widget +mListView = ((ListView) findViewById(android.R.id.list)); +// Creates a CursorAdapter +mAdapter = + new SimpleCursorAdapter( + this, // Current context + R.layout.logitem, // View for each item in the list + null, // Don't provide the cursor yet + FROM_COLUMNS, // List of cursor columns to display + TO_FIELDS, // List of TextViews in each line + 0 // flags +); +// Links the adapter to the ListView +mListView.setAdapter(mAdapter); ++
+ The next snippet shows an implementation of + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()} + that moves the query results in the returned {@link android.database.Cursor} to the + {@link android.support.v4.widget.SimpleCursorAdapter}. Changing the + {@link android.database.Cursor} in the + {@link android.support.v4.widget.SimpleCursorAdapter} triggers a refresh of the + {@link android.widget.ListView} with the new data: +
+
+public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
+{
+ /*
+ * Move the results into the adapter. This
+ * triggers the ListView to re-display.
+ */
+ mAdapter.swapCursor(cursor);
+}
+
++ The loader framework resets the {@link android.support.v4.content.CursorLoader} whenever the + {@link android.database.Cursor} becomes invalid. This usually occurs because the data associated + with the {@link android.database.Cursor} has changed. Before re-running the query, + the framework calls your implementation of + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. In + this callback, make sure to prevent memory leaks by deleting all references to the current + {@link android.database.Cursor}. Once you return from + {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}, + the loader framework re-runs the query. +
++ For example: +
+
+public void onLoaderReset(Loader<Cursor> loader)
+{
+ // Remove the reference to the current Cursor
+ mAdapter.swapCursor(null);
+}
+
diff --git a/docs/html/training/load-data-background/index.jd b/docs/html/training/load-data-background/index.jd
new file mode 100644
index 0000000000000..574a32cc0e40d
--- /dev/null
+++ b/docs/html/training/load-data-background/index.jd
@@ -0,0 +1,117 @@
+page.title=Loading Data in the Background
+trainingnavtop=true
+startpage=true
+
+@jd:body
++ A {@link android.support.v4.content.CursorLoader} runs a query against a + {@link android.content.ContentProvider} on a background thread and returns a + {@link android.database.Cursor} to the main thread. +
++ {@link android.support.v4.content.CursorLoader} has these advantages over alternate ways of + running a query: +
++ A {@link android.support.v4.content.CursorLoader} is limited in that the query must be + against a {@link android.net.Uri} and must return a {@link android.database.Cursor}. Because of + this, a {@link android.support.v4.content.CursorLoader} can only run a query against a + {@link android.content.ContentProvider}. +
++ This class describes how to define and use a {@link android.support.v4.content.CursorLoader}. + Examples in this class use the {@link android.support.v4 v4 support library} versions of + classes, which support platforms starting with Android 1.6. +
++ You create a {@link android.support.v4.content.CursorLoader} within a + loader framework. To set up the framework, you implement the + {@link android.support.v4.app.LoaderManager.LoaderCallbacks LoaderCallbacks<Cursor>} + as part of an {@link android.app.Activity}. In addition, to provide compatibility + compatible with platform versions starting with Android 1.6, you must extend the + {@link android.app.Activity} with the {@link android.support.v4.app.FragmentActivity} class. +
++ Note: A {@link android.support.v4.app.Fragment} is not a prerequisite for + {@link android.support.v4.content.CursorLoader}. As a convenience, the support library class + {@link android.support.v4.app.FragmentActivity} contains the fragment and the loader frameworks, + but they are completely independent of each other. +
++ Before you can use the loader framework, you need to initialize it. To do this, retrieve + a {@link android.support.v4.app.LoaderManager} object and call its + {@link android.support.v4.app.LoaderManager#initLoader initLoader()} method. +
++ If you do use one or more {@link android.support.v4.app.Fragment} objects in an + {@link android.app.Activity}, the {@link android.support.v4.app.LoaderManager} you retrieve is + available to all of them. +
++ To set up an {@link android.app.Activity} subclass to contain a + {@link android.support.v4.content.CursorLoader}, extend the subclass with + must extend {@link android.support.v4.app.FragmentActivity}, which provides the loader + framework, and implement the {@link android.support.v4.app.LoaderManager.LoaderCallbacks + LoaderCallbacks<Cursor>} interface, which specifies method signatures that the loader + framework uses to interact with the {@link android.app.Activity}. +
++ For example: +
++public class DisplayActivity extends FragmentActivity + implements LoaderManager.LoaderCallbacks<Cursor> ++
+ To get an instance {@link android.support.v4.app.LoaderManager} for use in your + {@link android.app.Activity}, call + {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager + FragmentActivity.getSupportLoaderManager()} at the beginning of the + {@link android.app.Activity#onCreate onCreate()} method. For example: +
+
+private LoaderManager mLoaderManager;
+public void onCreate() {
+...
+mLoaderManager = this.getSupportLoaderManager();
+
++ Once you have the {@link android.support.v4.app.LoaderManager} object, initialize + it by calling {@link android.support.v4.app.LoaderManager#initLoader initLoader()}. For + example: +
++// CursorLoader instance identifier +public static final int URL_LOADER = 0; +... +// Initializes the CursorLoader +getSupportLoaderManager().initLoader(URL_LOADER, null, this); +diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 4a5b0fadc5ddd..1c85ae8401882 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -58,7 +58,7 @@ - +