web-dev-qa-db-ja.com

setNotificationUriのメカニズムは何ですか?

CursorLoaderを実装したばかりで、うまく機能します。実際、テストするまで、基になるデータが変更されたときにListViewが自動的に更新されるとは思っていませんでした。これはどうやらsetNotificationUriの魔法です。

私の質問は、カーソル内のデータがいつ変更されたかをどのようにして知るのかということです。静かにどこかに追加の行を挿入するとします。基盤となるメカニズムは常にデータベースにクエリを実行し、過去のデータと比較しますか?データセットが大きい場合、それはひどく非効率的ではないでしょうか?

カーソルローダーを使用する前は、必要に応じて手動で更新していました。もうこれを行う必要がないのは素晴らしいことですが、CursorLoaderをバックグラウンドでこれに任せるのは効率的ですか?

28

どこか間違っていたら訂正してください。

ContentProviderquery(…)メソッドで次のようなものを呼び出します。

// 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);
}

誰かがデータを変更すると、ContentProviderContentResolverに変更について通知します。

getContext().getContentResolver().notifyChange(uri, null);

ContentResolverは、登録されているすべてのオブザーバーに通知します。

CursorLoaderによって登録されたオブザーバーは、新しいデータをロードするように強制します。

38
StenaviN