28

我刚刚实现了一个 CursorLoader,效果很好!事实上,我不相信我的 ListView 会在底层数据发生变化时自动更新,直到我测试它。这显然是 setNotificationUri 的魔力。

我的问题是,它如何知道游标中的数据何时发生了变化?假设我悄悄地在某处插入了一行。底层机制是否不断地查询数据库并与过去的数据进行比较?如果数据集很大,那会不会非常低效?

在我使用游标加载器之前,我会在必要时手动刷新。我不必再这样做真是太好了,但是让 CursorLoader 在后台执行此操作是否有效?

4

1 回答 1

38

如果我在某个地方错了,请纠正我。

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强制它加载新数据。

于 2012-08-03T21:00:21.237 回答