Cursorloader Not Updating After Data Change

CursorLoader not updating after data change

Did you call setNotificationUri(ContentResolver cr, Uri uri) on the Cursor before returning it in ContentProvider.query()?

And did you call getContext().getContentResolver().notifyChange(uri, null) in the 'insert' method of your ContentProvider?

EDIT:

To get a ContentResolver call getContext().getContentResolver() in your ContentProvider.

CursorLoader not updating after notifyChange call

Solved it, but since I haven't seen this documented, here's my solution.

I was returning a MergeCursor from my ContentProvider, basically just concatenating a list of cursors. I had

    @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Generate an array of Cursors

MergeCursor mergCursor = new MergeCursor(cursorArray);

// notify potential listeners
mergCursor.setNotificationUri(getContext().getContentResolver(), uri);

return mergCursor;
}

And my CursorLoader was never receiving the notification. However, as MergeCursor is basically just an Array of Cursor, you need to set the notification uri on each cursor in your MergeCursor.

    @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Generate an array of Cursors

// set the notification uris...
for (Cursor cursor : cursorArray) {
cursor.setNotificationUri(getContext().getContentResolver(), uri);
}

MergeCursor mergCursor = new MergeCursor(cursorArray);

return mergCursor;
}

Now everything works as expected!

CursorLoader does not refresh if notifyChange() is called before CursorLoader registers ContentObserver

My approach is to register the observer before starting with the loading of the cursor. You need to register for the Uri instead of for the cursor.

 getActivity().getContentResolver().registerContentObserver(
your_Uri, true,
new YourObserver(mHandler));

getLoaderManager().initLoader(0, null, this);

CursorLoader not refreshing on data change

Cursor result = database.rawQuery(evidenceQuery, null);
result.setNotificationUri(getContext().getContentResolver(), TODO_EVIDENCES_CONTENT_URI);
return database.rawQuery(evidenceQuery, null);

You're not returning the Cursor that you called setNotificationUri on. You're returning a second rawQuery cursor. What you want is:

Cursor result = database.rawQuery(evidenceQuery, null);
result.setNotificationUri(getContext().getContentResolver(), TODO_EVIDENCES_CONTENT_URI);
return result;

CursorLoader does not refresh data the second time

Because in SQLite autoincremented id counter does not resets, so I just replaced this:

Cursor cursor = mMoviesAdapter.getItem(position + 1);
Uri uri = MoviesEntry.buildMoviesUri((long) cursor.getPosition());

by this:

Uri uri = MoviesEntry.buildMoviesUri(mMoviesAdapter.getItemId(position));

in my main fragment. And everything works fine.

MergeCursor not updating after data change

So the way I got this working (whether it's right or not) is by further subclassing my AsyncTaskLoader class:

    @Override
protected void onStartLoading() {

forceLoad();
}

Essentially by adding the forceLoad(); to the onStartLoading() method the everything now works as expected. I was able to remove all the additional calls to notifyDataSetChanged() and notifications to URIs. That single line fixed everything. If someone has a better solution please do let me know, but for now this is what I got.



Related Topics



Leave a reply



Submit