• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=ローダ
2parent.title=アクティビティ
3parent.link=activities.html
4@jd:body
5<div id="qv-wrapper">
6<div id="qv">
7    <h2>本書の内容</h2>
8    <ol>
9    <li><a href="#summary">Loader API の概要</a></li>
10    <li><a href="#app">アプリケーションでローダを使用する</a>
11      <ol>
12        <li><a href="#requirements"></a></li>
13        <li><a href="#starting">ローダを開始する</a></li>
14        <li><a href="#restarting">ローダを再開する</a></li>
15        <li><a href="#callback">LoaderManager コールバックを使用する</a></li>
16      </ol>
17    </li>
18    <li><a href="#example">例</a>
19       <ol>
20         <li><a href="#more_examples">その他の例</a></li>
21        </ol>
22    </li>
23  </ol>
24
25  <h2>キークラス</h2>
26    <ol>
27      <li>{@link android.app.LoaderManager}</li>
28      <li>{@link android.content.Loader}</li>
29
30    </ol>
31
32    <h2>関連サンプル</h2>
33   <ol>
34     <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
35LoaderCursor</a></li>
36     <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
37LoaderThrottle</a></li>
38   </ol>
39  </div>
40</div>
41
42<p>Android 3.0 で導入されたローダによって、アクティビティやフラグメントでのデータの非同期ロードが簡単になりました。
43ローダには、次の 3 つの特徴があります。</p>
44  <ul>
45    <li>すべての {@link android.app.Activity} と {@link
46android.app.Fragment} で使用できる。</li>
47    <li>非同期のデータロードを提供する。</li>
48    <li>データのソースを監視し、コンテンツが変更されたときに新しい結果を配信する。
49</li>
50    <li>設定の変更後に再作成されると、自動的に最後のローダのカーソルに再接続するため、
51再度データを問い合わせる必要がない。
52</li>
53  </ul>
54
55<h2 id="summary">Loader API の概要</h2>
56
57<p>アプリケーションでローダを使用するのに必要になりそうなクラスやインターフェースは複数あります。
58次の表で、それらの概要をまとめました。</p>
59
60<table>
61  <tr>
62    <th>クラス/インターフェース</th>
63    <th>説明</th>
64  </tr>
65  <tr>
66    <td>{@link android.app.LoaderManager}</td>
67    <td>1 つ以上の {@link
68android.content.Loader} インスタンスを管理するための、{@link android.app.Activity} や {@link android.app.Fragment} に関連した抽象クラスです。
69これにより、アプリケーションは {@link android.app.Activity} や {@link android.app.Fragment} のライフサイクルと連動して長時間の操作を管理できるようになります。最も一般的なのは、{@link android.content.CursorLoader} で使用する方法ですが、アプリケーションでは他のタイプのデータのロード用に、独自のローダを自由に作成することもできます。
70
71
72
73
74    <br />
75    <br />
76    1 つのアクティビティやフラグメントごとに、{@link android.app.LoaderManager} は 1 つだけ存在しますが、{@link android.app.LoaderManager} は複数のローダを持つことができます。
77</td>
78  </tr>
79  <tr>
80    <td>{@link android.app.LoaderManager.LoaderCallbacks}</td>
81    <td>クライアントが {@link
82android.app.LoaderManager} とやり取りするためのコールバック インターフェースです。たとえば、{@link
83android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} コールバック メソッドを使用してと新しいローダを作成します。
84</td>
85  </tr>
86  <tr>
87    <td>{@link android.content.Loader}</td>
88    <td>非同期のデータロードを実行する抽象クラスです。これは、ローダの基本クラスです。
89通常は {@link
90android.content.CursorLoader} を使用しますが、独自のサブクラスを実装することもできます。ローダがアクティブな間は、データのソースを管理し、コンテンツが変更されたときに新しい結果を配信します。
91
92 </td>
93  </tr>
94  <tr>
95    <td>{@link android.content.AsyncTaskLoader}</td>
96    <td>処理を行うための {@link android.os.AsyncTask} を提供する抽象的なローダです。</td>
97  </tr>
98  <tr>
99    <td>{@link android.content.CursorLoader}</td>
100    <td>{@link android.content.ContentResolver} に問い合わせて {@link
101android.database.Cursor} を返す{@link android.content.AsyncTaskLoader} のサブクラスです。
102これは、カーソルのクエリ用に標準的な方法で {@link
103android.content.Loader} プロトコルを実装するクラスで、アプリケーションの UI をブロックせずにバックグラウンドでカーソルのクエリを実行するように、{@link android.content.AsyncTaskLoader} を基に構築されています。{@link
104android.content.ContentProvider} からデータを非同期的にロードする際は、フラグメントの API やアクティビティの API 経由でマネージド クエリを実行するのではなく、このローダを使用するのが最適です。
105
106
107
108</td>
109  </tr>
110</table>
111
112<p>上の表のクラスとインターフェースは、アプリケーションでローダを実装する際に使用する必須コンポーネントです。
113作成するローダごとにこれらすべてが必要になるわけではありませんが、{@link
114android.app.LoaderManager} への参照は、ローダを初期化したり {@link
115android.content.CursorLoader} などの {@link android.content.Loader} を実装したりするには {@link
116android.app.LoaderManager} への参照が常に必要になります。
117次のセクションでは、アプリケーションでのこれらのクラスとインターフェースの使用方法を説明します。
118</p>
119
120<h2 id ="app">アプリケーションでローダを使用する</h2>
121<p>このセクションでは、Android アプリケーションのローダの使用方法について説明します。通常、ローダを使用するアプリケーションには次の内容が含まれます。
122</p>
123<ul>
124  <li>{@link android.app.Activity} または {@link android.app.Fragment}。</li>
125  <li>{@link android.app.LoaderManager} のインスタンス。</li>
126  <li>{@link
127android.content.ContentProvider} でサポートされているデータをロードする {@link android.content.CursorLoader}。あるいは、{@link android.content.Loader} や{@link android.content.AsyncTaskLoader} の独自のサブクラスを実装して他のソースからデータをロードすることもできます。
128
129</li>
130  <li>{@link android.app.LoaderManager.LoaderCallbacks} の実装。ここで、新しいローダを作成して既存のローダへの参照を管理します。
131
132</li>
133<li>{@link
134android.widget.SimpleCursorAdapter} などのローダのデータを表示する方法。</li>
135  <li>{@link android.content.CursorLoader} を使用するときの、{@link android.content.ContentProvider} などのデータ ソース。
136</li>
137</ul>
138<h3 id="starting">ローダを開始する</h3>
139
140<p>{@link android.app.LoaderManager} は 1 つ以上の {@link
141android.content.Loader} インスタンスを {@link android.app.Activity} や {@link android.app.Fragment} 内で管理します。
1421 つのアクティビティやフラグメントごとに、{@link
143android.app.LoaderManager} は 1 つだけ存在します。</p>
144
145<p>通常は、アクティビティの {@link
146android.app.Activity#onCreate onCreate()} メソッドか、フラグメントの {@link android.app.Fragment#onActivityCreated onActivityCreated()} メソッド内で {@link android.content.Loader} を初期化します。
147
148その方法は次のとおりです。
149</p>
150
151<pre>// Prepare the loader.  Either re-connect with an existing one,
152// or start a new one.
153getLoaderManager().initLoader(0, null, this);</pre>
154
155<p>{@link android.app.LoaderManager#initLoader initLoader()} メソッドが次のパラメータを受け取ります。
156</p>
157<ul>
158  <li>ローダを識別する一意の ID。この例では、ID は 0 です。</li>
159<li>ローダの構築時に提供する任意の引数(この例では <code>null</code>)。
160</li>
161
162<li>{@link android.app.LoaderManager} がローダのイベントを報告する際に呼び出す {@link android.app.LoaderManager.LoaderCallbacks} の実装。
163この例では、ローカルクラスが {@link
164android.app.LoaderManager.LoaderCallbacks} インターフェースを実装するため、自身の {@code this} に参照を渡します。
165
166</li>
167</ul>
168<p>{@link android.app.LoaderManager#initLoader initLoader()} の呼び出しによって、ローダが初期化され、アクティブになります。
169結果には次の 2 つの可能性があります。</p>
170<ul>
171  <li>ID で指定されたローダが既に存在する場合は、最後に作成されたローダが再利用されます。
172</li>
173  <li>ID で指定したローダが存在<em>しない</em>場合、{@link android.app.LoaderManager#initLoader initLoader()} が {@link android.app.LoaderManager.LoaderCallbacks} メソッドの {@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} をトリガーします。ここで、インスタンスを作成して新しいローダを返すコードを実装します。詳細については、<a href="#onCreateLoader">onCreateLoader</a> のセクションをご覧ください。
174
175
176
177</li>
178</ul>
179<p>いずれの場合でも、その {@link android.app.LoaderManager.LoaderCallbacks} の実装はローダに関連付けられ、ローダの状態が変化したときに呼び出されます。
180
181この呼び出しの時点で、呼び出し側が開始された状態にあり、要求されたローダが既に存在し、データを生成済みの場合は、システムはただちに {@link
182android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()} を呼び出す({@link android.app.LoaderManager#initLoader initLoader()} の間に)ため、それに備えておく必要があります。
183
184
185
186このコールバックの詳細については、<a href="#onLoadFinished">
187onLoadFinished</a> をご覧ください。</p>
188
189<p>{@link android.app.LoaderManager#initLoader initLoader()} メソッドは作成された {@link android.content.Loader} を返しますが、そこへの参照はキャプチャしないことに注意してください。
190
191{@link android.app.LoaderManager} は自動的にローダの生存状態を管理します。
192{@link android.app.LoaderManager} は必要に応じて開始と停止を行いし、ローダとそれに関連付けられたコンテンツの状態を管理します。
193
194このことからもわかるように、ローダと直接やり取りすることはほとんどありません(ローダの動作を微調整するローダ メソッドの使用例については、<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> のサンプルをご覧ください)。
195
196特定のイベントが発生したときにローディングの処理に干渉することを目的に、{@link
197android.app.LoaderManager.LoaderCallbacks} を使用することがよくあります。
198
199このトピックの詳細については、<a href="#callback">LoadManager コールバックを使用する</a>をご覧ください。</p>
200
201<h3 id="restarting">ローダを再開する</h3>
202
203<p>上記のように {@link android.app.LoaderManager#initLoader initLoader()} を使用する場合、指定した ID があれば既存のローダを使用し、なければ新たに作成します。
204
205ただし、古いデータを破棄して最初からやり直したいこともあります。
206</p>
207
208<p>古いデータを破棄するには、{@link
209android.app.LoaderManager#restartLoader restartLoader()} を使用します。たとえば、この {@link android.widget.SearchView.OnQueryTextListener} を実装すると、ユーザーのクエリが変化したときにローダが再開されます。
210
211新しい検索フィルタを使用して新しいクエリを実行できるように、ローダは再開される必要があります。
212</p>
213
214<pre>
215public boolean onQueryTextChanged(String newText) {
216    // Called when the action bar search text has changed.  Update
217    // the search filter, and restart the loader to do a new query
218    // with this filter.
219    mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
220    getLoaderManager().restartLoader(0, null, this);
221    return true;
222}</pre>
223
224<h3 id="callback">LoaderManager コールバックを使用する</h3>
225
226<p>{@link android.app.LoaderManager.LoaderCallbacks} はクライアントが {@link android.app.LoaderManager} とやり取りできるようにするコールバック インターフェースです。
227 </p>
228<p>特に、{@link android.content.CursorLoader} のローダでは、停止後もデータを保持しておくことが望まれます。
229これにより、アプリケーションがアクティビティやフラグメントの {@link android.app.Activity#onStop
230onStop()} メソッドや {@link android.app.Activity#onStart onStart()} メソッド全体でデータを維持することができるので、ユーザーがアプリケーションに戻ったときにデータの再ロードを待つ必要がありません。
231
232
233新しいローダを作成するタイミングを知りたいときや、ローダのデータの使用を停止するタイミングをアプリケーションに伝えるときは、{@link android.app.LoaderManager.LoaderCallbacks} メソッドを使用します。
234
235</p>
236
237<p>{@link android.app.LoaderManager.LoaderCallbacks} には次のメソッドが含まれています。
238</p>
239<ul>
240  <li>{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} — 指定された ID の新しい {@link android.content.Loader} をインスタンス化して返します。
241
242</li></ul>
243<ul>
244  <li> {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}— 前に作成されたローダがロードを完了した時に呼び出されます。
245
246</li></ul>
247<ul>
248  <li>{@link android.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()} — 前に作成されたローダがリセットされ、データが利用不可になったときに呼び出されます。
249
250
251</li>
252</ul>
253<p>これらのメソッドについては、次のセクションで詳しく説明します。</p>
254
255<h4 id ="onCreateLoader">onCreateLoader</h4>
256
257<p>ローダにアクセスしようとしたとき(たとえば、{@link
258android.app.LoaderManager#initLoader initLoader()} 経由など)、ID で指定したローダが存在するかどうかを確認されます。
259存在しない場合は、{@link
260android.app.LoaderManager.LoaderCallbacks} メソッドの {@link
261android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} をトリガーします。ここで、新しいローダを作成します。
262通常は、{@link
263android.content.CursorLoader} になりますが、独自の {@link
264android.content.Loader} サブクラスを実装することもできます。 </p>
265
266<p>この例では、{@link
267android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
268コールバック メソッドが {@link android.content.CursorLoader} を作成します。{@link android.content.CursorLoader}は、そのコンストラクタ メソッドを使用して構築する必要があり、{@link
269android.content.ContentProvider} へのクエリを実行するのに必要なすべての情報が必要になります。
270
271具体的に必要な情報は次のとおりです。</p>
272<ul>
273  <li><em>uri</em> — 取得するコンテンツの URI。 </li>
274  <li><em>projection</em> — 返す列のリスト。<code>null</code> を渡すとすべての列が返されるため、効率的ではありません。
275 </li>
276  <li><em>selection</em> — SQL WHERE 句の書式で返す行を宣言するフィルタ(WHERE 自体は除く)。
277<code>null</code> を渡すと指定した URI のすべての行が返されます。
278 </li>
279  <li><em>selectionArgs</em> — selection に ? を含めると、selection に表示される順序で <em>selectionArgs</em> の値に置き換えられます。
280
281この値は、Strings 配列でバインドされます。 </li>
282  <li><em>sortOrder</em> — SQL
283ORDER BY 句(ORDER 自体は除く)の形式で行を順序付けします。<code>null</code> を渡すとデフォルトのソート順序が使用されるため、順序が付けられない場合があります。
284</li>
285</ul>
286<p>次に例を示します。</p>
287<pre>
288 // If non-null, this is the current filter the user has provided.
289String mCurFilter;
290...
291public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
292    // This is called when a new Loader needs to be created.  This
293    // sample only has one Loader, so we don't care about the ID.
294    // First, pick the base URI to use depending on whether we are
295    // currently filtering.
296    Uri baseUri;
297    if (mCurFilter != null) {
298        baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
299                  Uri.encode(mCurFilter));
300    } else {
301        baseUri = Contacts.CONTENT_URI;
302    }
303
304    // Now create and return a CursorLoader that will take care of
305    // creating a Cursor for the data being displayed.
306    String select = &quot;((&quot; + Contacts.DISPLAY_NAME + &quot; NOTNULL) AND (&quot;
307            + Contacts.HAS_PHONE_NUMBER + &quot;=1) AND (&quot;
308            + Contacts.DISPLAY_NAME + &quot; != '' ))&quot;;
309    return new CursorLoader(getActivity(), baseUri,
310            CONTACTS_SUMMARY_PROJECTION, select, null,
311            Contacts.DISPLAY_NAME + &quot; COLLATE LOCALIZED ASC&quot;);
312}</pre>
313<h4 id="onLoadFinished">onLoadFinished</h4>
314
315<p>このメソッドは、前に作成したローダがロードを完了したときに呼び出されます。このメソッドは、このローダが提供した最後のデータが解放される前に呼び出されることが保証されています。
316
317この時点で、すべての古いデータを削除する必要がありますが(まもなく解放されるため)、データの所有者はローダでありローダが処理するため、自身でデータを解放しないようにしてください。
318
319</p>
320
321
322<p>アプリケーションがもうデータを使用していないことを検知すると、ローダがデータを解放します。
323たとえば、データが {@link
324android.content.CursorLoader} からのカーソルの場合は、自身で {@link
325android.database.Cursor#close close()} を呼び出さないようにしてください。カーソルが {@link android.widget.CursorAdapter} に置かれている場合は、古い {@link android.database.Cursor} がクローズされないように {@link
326android.widget.SimpleCursorAdapter#swapCursor swapCursor()} メソッドを使用する必要があります。
327
328次に例を示します。</p>
329
330<pre>
331// This is the Adapter being used to display the list's data.<br
332/>SimpleCursorAdapter mAdapter;
333...
334
335public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
336    // Swap the new cursor in.  (The framework will take care of closing the
337    // old cursor once we return.)
338    mAdapter.swapCursor(data);
339}</pre>
340
341<h4 id="onLoaderReset">onLoaderReset</h4>
342
343<p>このメソッドは、前に作成されたローダがリセットされ、データが利用できなくなったときに呼び出されます。
344このコールバックにより、データが解放されるタイミングがわかり、そのデータへの参照を削除できます。
345  </p>
346<p>この実装では、<code>null</code> の値を使用して {@link android.widget.SimpleCursorAdapter#swapCursor swapCursor()} を呼び出します。
347
348</p>
349
350<pre>
351// This is the Adapter being used to display the list's data.
352SimpleCursorAdapter mAdapter;
353...
354
355public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
356    // This is called when the last Cursor provided to onLoadFinished()
357    // above is about to be closed.  We need to make sure we are no
358    // longer using it.
359    mAdapter.swapCursor(null);
360}</pre>
361
362
363<h2 id="example">例</h2>
364
365<p>以下は、連絡先のコンテンツ プロバイダに対するクエリの結果が含まれた {@link android.widget.ListView} を表示する {@link
366android.app.Fragment} の完全な実装の例です。
367{@link
368android.content.CursorLoader} を使用してプロバイダへのクエリを管理しています。</p>
369
370<p>この例にあるように、アプリケーションがユーザーの連絡先にアクセスするには、マニフェストに {@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS} の許可を含める必要があります。
371
372</p>
373
374<pre>
375public static class CursorLoaderListFragment extends ListFragment
376        implements OnQueryTextListener, LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
377
378    // This is the Adapter being used to display the list's data.
379    SimpleCursorAdapter mAdapter;
380
381    // If non-null, this is the current filter the user has provided.
382    String mCurFilter;
383
384    @Override public void onActivityCreated(Bundle savedInstanceState) {
385        super.onActivityCreated(savedInstanceState);
386
387        // Give some text to display if there is no data.  In a real
388        // application this would come from a resource.
389        setEmptyText(&quot;No phone numbers&quot;);
390
391        // We have a menu item to show in action bar.
392        setHasOptionsMenu(true);
393
394        // Create an empty adapter we will use to display the loaded data.
395        mAdapter = new SimpleCursorAdapter(getActivity(),
396                android.R.layout.simple_list_item_2, null,
397                new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
398                new int[] { android.R.id.text1, android.R.id.text2 }, 0);
399        setListAdapter(mAdapter);
400
401        // Prepare the loader.  Either re-connect with an existing one,
402        // or start a new one.
403        getLoaderManager().initLoader(0, null, this);
404    }
405
406    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
407        // Place an action bar item for searching.
408        MenuItem item = menu.add(&quot;Search&quot;);
409        item.setIcon(android.R.drawable.ic_menu_search);
410        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
411        SearchView sv = new SearchView(getActivity());
412        sv.setOnQueryTextListener(this);
413        item.setActionView(sv);
414    }
415
416    public boolean onQueryTextChange(String newText) {
417        // Called when the action bar search text has changed.  Update
418        // the search filter, and restart the loader to do a new query
419        // with this filter.
420        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
421        getLoaderManager().restartLoader(0, null, this);
422        return true;
423    }
424
425    @Override public boolean onQueryTextSubmit(String query) {
426        // Don't care about this.
427        return true;
428    }
429
430    @Override public void onListItemClick(ListView l, View v, int position, long id) {
431        // Insert desired behavior here.
432        Log.i(&quot;FragmentComplexList&quot;, &quot;Item clicked: &quot; + id);
433    }
434
435    // These are the Contacts rows that we will retrieve.
436    static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
437        Contacts._ID,
438        Contacts.DISPLAY_NAME,
439        Contacts.CONTACT_STATUS,
440        Contacts.CONTACT_PRESENCE,
441        Contacts.PHOTO_ID,
442        Contacts.LOOKUP_KEY,
443    };
444    public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
445        // This is called when a new Loader needs to be created.  This
446        // sample only has one Loader, so we don't care about the ID.
447        // First, pick the base URI to use depending on whether we are
448        // currently filtering.
449        Uri baseUri;
450        if (mCurFilter != null) {
451            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
452                    Uri.encode(mCurFilter));
453        } else {
454            baseUri = Contacts.CONTENT_URI;
455        }
456
457        // Now create and return a CursorLoader that will take care of
458        // creating a Cursor for the data being displayed.
459        String select = &quot;((&quot; + Contacts.DISPLAY_NAME + &quot; NOTNULL) AND (&quot;
460                + Contacts.HAS_PHONE_NUMBER + &quot;=1) AND (&quot;
461                + Contacts.DISPLAY_NAME + &quot; != '' ))&quot;;
462        return new CursorLoader(getActivity(), baseUri,
463                CONTACTS_SUMMARY_PROJECTION, select, null,
464                Contacts.DISPLAY_NAME + &quot; COLLATE LOCALIZED ASC&quot;);
465    }
466
467    public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
468        // Swap the new cursor in.  (The framework will take care of closing the
469        // old cursor once we return.)
470        mAdapter.swapCursor(data);
471    }
472
473    public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
474        // This is called when the last Cursor provided to onLoadFinished()
475        // above is about to be closed.  We need to make sure we are no
476        // longer using it.
477        mAdapter.swapCursor(null);
478    }
479}</pre>
480<h3 id="more_examples">その他の例</h3>
481
482<p><strong>ApiDemos</strong> には、ローダの使用方法を示す他のサンプルがいくつか用意されています。
483</p>
484<ul>
485  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
486LoaderCursor</a> — 上記のスニペットの完全バージョン。
487</li>
488  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — スロットリングを使用して、データの変更時にコンテンツ プロバイダのクエリ数を軽減する方法の例です。
489</li>
490</ul>
491
492<p>SDK サンプルのダウンロードとインストールの詳細については、<a href="http://developer.android.com/resources/samples/get.html">Getting the Samples</a> をご覧ください。
493 </p>
494
495