CursorLoaderを実装したばかりで、うまく機能します。実際、テストするまで、基になるデータが変更されたときにListViewが自動的に更新されるとは思っていませんでした。これはどうやらsetNotificationUriの魔法です。
私の質問は、カーソル内のデータがいつ変更されたかをどのようにして知るのかということです。静かにどこかに追加の行を挿入するとします。基盤となるメカニズムは常にデータベースにクエリを実行し、過去のデータと比較しますか?データセットが大きい場合、それはひどく非効率的ではないでしょうか?
カーソルローダーを使用する前は、必要に応じて手動で更新していました。もうこれを行う必要がないのは素晴らしいことですが、CursorLoaderをバックグラウンドでこれに任せるのは効率的ですか?
どこか間違っていたら訂正してください。
ContentProvider
はquery(…)
メソッドで次のようなものを呼び出します。
// Tell the cursor what uri to watch, so it knows when its source data changes
cursor.setNotificationUri(getContext().getContentResolver(), uri);
CursorLoader
カーソルを戻し、オブザーバーを登録します。
/* Runs on a worker thread */
@Override
public Cursor loadInBackground() {
Cursor cursor = getContext().getContentResolver().query(mUri, mProjection,
mSelection, mSelectionArgs, mSortOrder);
if (cursor != null) {
// Ensure the cursor window is filled
cursor.getCount();
registerContentObserver(cursor, mObserver);
}
return cursor;
}
/**
* Registers an observer to get notifications from the content provider
* when the cursor needs to be refreshed.
*/
void registerContentObserver(Cursor cursor, ContentObserver observer) {
cursor.registerContentObserver(mObserver);
}
誰かがデータを変更すると、ContentProvider
はContentResolver
に変更について通知します。
getContext().getContentResolver().notifyChange(uri, null);
ContentResolver
は、登録されているすべてのオブザーバーに通知します。
CursorLoader
によって登録されたオブザーバーは、新しいデータをロードするように強制します。