What is cursor.setNotificationUri() used for?

后端 未结 3 1883
太阳男子
太阳男子 2020-12-05 00:18

I did research on how to use ContentProviders and Loaders from this tutorial

How I see it: We have an Activity with ListView,

3条回答
  •  不知归路
    2020-12-05 01:16

    CursorLoader registers observer for the cursor, not to the URI.

    Look into CursorLoader's source code below. Notice that CursorLoader registers contentObserver to the cursor.

    /* Runs on a worker thread */
        @Override
        public Cursor loadInBackground() {
            synchronized (this) {
                if (isLoadInBackgroundCanceled()) {
                    throw new OperationCanceledException();
                }
                mCancellationSignal = new CancellationSignal();
            }
            try {
                Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
                        mSelectionArgs, mSortOrder, mCancellationSignal);
                if (cursor != null) {
                    try {
                        // Ensure the cursor window is filled.
                        cursor.getCount();
                        cursor.registerContentObserver(mObserver);
                    } catch (RuntimeException ex) {
                        cursor.close();
                        throw ex;
                    }
                }
                return cursor;
            } finally {
                synchronized (this) {
                    mCancellationSignal = null;
                }
            }
    

    The Cursor needs to call method setNotificationUri() to register mSelfObserver to the uri.

    //AbstractCursor.java
    public void setNotificationUri(ContentResolver cr, Uri notifyUri, int userHandle) {
            synchronized (mSelfObserverLock) {
                mNotifyUri = notifyUri;
                mContentResolver = cr;
                if (mSelfObserver != null) {
                    mContentResolver.unregisterContentObserver(mSelfObserver);
                }
                mSelfObserver = new SelfContentObserver(this);
                mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver, userHandle); // register observer to the uri
                mSelfObserverRegistered = true;
            }
        }
    

    Inside the contentProvider's insert, update, delete methods, you need to call getContext().getContentResolver().notifyChange(uri, null); to notify change to the uri observers.

    So if you don't call cursor#setNotificationUri(), your CursorLoader will not receive notification if data underlying that uri changes.

提交回复
热议问题