Alex Rivera | Logout

Data out of sync between a custom CursorLoader and a CursorAdapter backing a ListView

Asked 2012-07-18T12:00:48.433
29

Background:

I have a custom CursorLoader that works directly with SQLite Database instead of using a ContentProvider. This loader works with a ListFragment backed by a CursorAdapter. So far so good.

To simplify things, lets assume there is a Delete button on the UI. When user clicks this, I delete a row from the DB, and also call onContentChanged() on my loader. Also, on onLoadFinished() callback, I call notifyDatasetChanged() on my adapter so as to refresh the UI.

Problem:

When the delete commands happen in rapid succession, meaning the onContentChanged() is called in rapid succession, bindView() ends up to be working with stale data. What this means is a row has been deleted, but the ListView is still attempting to display that row. This leads to Cursor exceptions.

What am I doing wrong?

Code:

This is a custom CursorLoader (based on this advice by Ms. Diane Hackborn)

/**
 * An implementation of CursorLoader that works directly with SQLite database
 * cursors, and does not require a ContentProvider.
 * 
 */
public class VideoSqliteCursorLoader extends CursorLoader {

    /*
     * This field is private in the parent class. Hence, redefining it here.
     */
    ForceLoadContentObserver mObserver;

    public VideoSqliteCursorLoader(Context context) {
        super(context);
        mObserver = new ForceLoadContentObserver();

    }

    public VideoSqliteCursorLoader(Context context, Uri uri,
            String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        super(context, uri, projection, selection, selectionArgs, sortOrder);
        mObserver = new ForceLoadContentObserver();

    }

    /*
     * Ma
Edit
Report

1 Answer

0

A had the same problem. I solved it by:

@Override
public void onResume() {
    super.onResume();  // Always call the superclass method first
    if (some_condition) {
        getSupportLoaderManager().getLoader(LOADER_ID).onContentChanged();
    }
}
answered 2013-06-13T13:09:36.937

Your Answer