setNotificationUri的机制是什么?

Bha*_*ark 27 database android cursor

我刚刚实现了一个CursorLoader,效果很好!事实上,我不相信我的ListView会在基础数据发生变化时自动更新,直到我测试它为止.这显然是setNotificationUri的神奇之处.

我的问题是,它如何知道光标中的数据何时发生了变化?说我在某处静静地插入一行.底层机制是否经常查询数据库并将其与过去的数据进行比较?如果数据集很大,这不是非常低效吗?

在我使用游标加载器之前,我会在必要时手动刷新.很高兴我不再需要这样做,但是让CursorLoader在后台使用它是否有效?

Ste*_*viN 38

如果我错了,请纠正我.

ContentProviderquery(…)方法中调用这样的东西:

// Tell the cursor what uri to watch, so it knows when its source data changes
cursor.setNotificationUri(getContext().getContentResolver(), uri);
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

当有人修改数据时,ContentProvider通知ContentResolver有关更改:

getContext().getContentResolver().notifyChange(uri, null);
Run Code Online (Sandbox Code Playgroud)

ContentResolver 反过来通知所有注册观察员.

注册的观察者CursorLoader强制它加载新数据.

  • @MarcinCzech:"即使我通过SQLiteDatabase而不是ContentProvider更新数据库,也会重启CursorLoader吗?" - 不.您必须通过`ContentProvider`进行所有更新,并且`ContentProvider`必须进行适当的调用以绑定到观察者框架. (10认同)
  • 我从SDK中引用了"CursorLoader"类的源代码 (2认同)