blob: ce0024f031c2674c791758169a3517dbd4e09329 [file] [log] [blame]
Joe Malinba34f092012-11-05 17:22:24 -08001page.title=Handling the Results
2trainingnavtop=true
3startpage=true
4
5@jd:body
6
7<!-- This is the training bar -->
8<div id="tb-wrapper">
9 <div id="tb">
10<h2>This lesson teaches you to</h2>
11<ol>
12 <li>
13 <a href="#HandleResults">Handle Query Results</a>
14 </li>
15 <li>
16 <a href="#HandleReset">Delete Old Cursor References</a></li>
17</ol>
18
19<h2>Try it out</h2>
20<div class="download-box">
21 <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
22 <p class="filename">ThreadSample.zip</p>
23</div>
24
25 </div>
26</div>
27
28<p>
29 As shown in the previous lesson, you should begin loading your data with a
30 {@link android.support.v4.content.CursorLoader} in your implementation of
31 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader
32 onCreateLoader()}. The loader then provides the query results to your
33 {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity} in your
34 implementation of {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished
35 LoaderCallbacks.onLoadFinished()}. One of the incoming arguments to this method is a
36 {@link android.database.Cursor} containing the query results. You can use this object to
37 update your data display or do further processing.
38</p>
39<p>
40 Besides
41 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} and
42 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()},
43 you also have to implement
44 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}.
45 This method is invoked when {@link android.support.v4.content.CursorLoader} detects
46 that data associated with the {@link android.database.Cursor} has changed. When the
47 data changes, the framework also re-runs the current query.
48</p>
49<h2 id="HandleResults">Handle Query Results</h2>
50<p>
51 To display {@link android.database.Cursor} data returned by
52 {@link android.support.v4.content.CursorLoader}, use a
53 {@link android.view.View} class that implements {@link android.widget.AdapterView} and
54 provide the view with an adapter that implements
55 {@link android.support.v4.widget.CursorAdapter}. The system then automatically moves data from
56 the {@link android.database.Cursor} to the view.
57</p>
58<p>
59 You can set up the linkage between the view and adapter before you have any data to display,
60 and then move a {@link android.database.Cursor} into the adapter in the
61 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
62 method. As soon as you move the {@link android.database.Cursor} into the adapter, the
63 system automatically updates the view. This also happens if you change the contents of the
64 {@link android.database.Cursor}.
65</p>
66<p>
67 For example:
68</p>
69<pre>
70public String[] mFromColumns = {
71 DataProviderContract.IMAGE_PICTURENAME_COLUMN
72};
73public int[] mToFields = {
74 R.id.PictureName
75};
76// Gets a handle to a List View
77ListView mListView = (ListView) findViewById(R.id.dataList);
78/*
79 * Defines a SimpleCursorAdapter for the ListView
80 *
81 */
82SimpleCursorAdapter mAdapter =
83 new SimpleCursorAdapter(
84 this, // Current context
85 R.layout.list_item, // Layout for a single row
86 null, // No Cursor yet
87 mFromColumns, // Cursor columns to use
88 mToFields, // Layout fields to use
89 0 // No flags
90 );
91// Sets the adapter for the view
92mListView.setAdapter(mAdapter);
93...
94/*
95 * Defines the callback that {@link android.support.v4.content.CursorLoader} calls
96 * when it's finished its query
97 */
98&#64;Override
99public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
100 ...
101 /*
102 * Moves the query results into the adapter, causing the
103 * ListView fronting this adapter to re-display
104 */
105 mAdapter.changeCursor(cursor);
106}
107</pre>
108<h2 id="HandleReset">Delete Old Cursor References</h2>
109<p>
110 The {@link android.support.v4.content.CursorLoader} is reset whenever its
111 {@link android.database.Cursor} becomes invalid. This usually occurs because the data associated
112 with the {@link android.database.Cursor} has changed. Before re-running the query,
113 the framework calls your implementation of
114 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. In
115 this callback, you should delete all references to the current {@link android.database.Cursor}
116 in order to prevent memory leaks. Once
117 {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}
118 finishes, {@link android.support.v4.content.CursorLoader} re-runs its query.
119</p>
120<p>
121 For example:
122</p>
123<pre>
124/*
125 * Invoked when the CursorLoader is being reset. For example, this is
126 * called if the data in the provider changes and the Cursor becomes stale.
127 */
128&#64;Override
129public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
130
131 /*
132 * Clears out the adapter's reference to the Cursor.
133 * This prevents memory leaks.
134 */
135 mAdapter.changeCursor(null);
136}
137</pre>