I did research on how to use ContentProviders
and Loaders from this tutorial
How I see it:
We have an Activity
with ListView
, SimpleCursorAdapter
and CursorLoader
. We also implement ContentProvider
.
In an Activity
we can call getContentResolver().insert(URI, contentValues);
via a button click.
In our implementation of ContentProvider
, at the end of insert()
method, we call getContentResolver().notifyChange(URI, null);
and our CursorLoader
will receive message that it should reload data and update UI. Also if we use FLAG_REGISTER_CONTENT_OBSERVER
in SimpleCursorAdapter
it will also receive message and its method onContentChanged()
will be called.
So our ListView will be updated if we insert, update or delete data.
Activity.startManagingCursor(cursor);
is deprecated, cursor.requery()
deprecated, so I do not see any practice sense from cursor.setNotificationUri()
.
I looked into setNotificationUri()
method's source code and saw that it calls mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver)
inside the method. Also CursorLoader
does the same. Finally cursor will receive message and the following method will be called inside Cursor:
protected void onChange(boolean selfChange) {
synchronized (mSelfObserverLock) {
mContentObservable.dispatchChange(selfChange, null);
// ...
}
}
But I can not make sense of this.
So my question is: why should we call cursor.setNotificationUri()
in query()
method of our ContentProvider
implementation?
If you call Cursor.setNotificationUri()
, Cursor will know what ContentProvider Uri it was created for.
CursorLoader
registers its own ForceLoadContentObserver
(which extends ContentObserver
) with the Context
's ContentResolver
for the URI you specified when calling setNotificationUri
.
So once that ContentResolver
knows that URI's content has been changed [ this happens when you call getContext().getContentResolver().notifyChange(uri, contentObserver);
inside ContentProvider
's insert()
, update()
and delete()
methods ] it notifies all the observers including CursorLoader's ForceLoadContentObserver
.
ForceLoadContentObserver
then marks Loader's mContentChanged as true