3

ローカルデータベースCursorLoaderからデータをロードする があります。SQLite

のデータは、実際にはリモート応答SQLiteのキャッシュされたコピーであるため、.APISQLiteCursorLoader

以下は、私のデータクエリに応答するために従う一連の手順ですContentProvider

  1. Query SQLiteforcached data. cursor.setNotificationUri(getContext().getContentResolver(), uri)は、返されたカーソルで呼び出されます。

  2. remote への非同期呼び出しを開始しますAPI。応答が受信されると、getContext().getContentResolver().notifyChange(uri, null)呼び出されます。

  3. 5がカーソルを受け取るのを遅らせるために数秒間スリープしますCursorLoader。(これは私の問題を簡単に再現するために行われます)。

  4. Step 1で取得したカーソルを に返しますCursorLoader

API非同期リモート呼び出しが完了する (そしてnotifyChange()呼び出される) という可能性は低いですが、可能性のあるシナリオでは、呼び出しによって取得したカーソルにCursorLoadera を登録することができます[ http://grepcode.com/file/repository.grepcode.com/java/extを参照してください。 /com.google.android/android/4.0.1_r1/android/content/CursorLoader.java#CursorLoader.loadInBackground%28%29 ] では、データ変更通知が見逃されるため、更新されたデータが表示されません。ContentObserverregisterContentObserver(cursor, mObserver)CursorLoaderActivity

この問題を回避するにLoaderCallBacksは、データが 2 回読み込まれるように記述します。最初にキャッシュされたデータのみが読み込まれ、次にrefresh要求が行われます。このようにして、 はコールが開始される前CursorLoaderに登録されます。ContentObserverrefresh

ただし、カーソルの自動更新をアドバタイズするため、これは理想的にはCursorLoaderそれ自体で処理する必要があります。CursorLoaderすべてでそれを行うとActivity、コードが大量に肥大化しActivityます。

4

2 に答える 2

1

私のアプローチは、カーソルの読み込みを開始する前にオブザーバーを登録することです。カーソルの代わりに Uri を登録する必要があります。

 getActivity().getContentResolver().registerContentObserver(
 your_Uri, true,
 new YourObserver(mHandler));

getLoaderManager().initLoader(0, null, this);
于 2013-07-28T22:14:44.540 に答える