31

What is difference between ContentObserver and DatasetObserver?

When one or another should be used?

I get Cursor with single row. I want to be notified about data changes - eg. when row is updated.

Which observer class should I register?

pixel
  • 21,352
  • 30
  • 113
  • 196

4 Answers4

29

If you are using a ContentProvider (via ContentResolver or Activity.managedQuery()) to get your data, simply attach a ContentObserver to your Cursor. The code in onChange() will be called whenever the ContentResolver broadcasts a notification for the Uri associated with your cursor.

Cursor myCursor = managedQuery(myUri, projection, where, whereArgs, sortBy);
myCursor.registerContentObserver(new ContentObserver() {
    @Override
    public void onChange(boolean selfChange) {
        // This cursor's Uri has been notified of a change
        // Call cursor.requery() or run managedQuery() again
    }

    @Override
    public boolean deliverSelfNotifications() {
        return true;
    }
}

Make sure your ContentProvider is a "good citizen" and registers the Uri with the cursor after a query:

cursor.setNotificationUri(getContentResolver(), uri);

It should also notify the ContentResolver of any changes to the underlying data (for instance, during insert, delete, and update operations on your SQLite database):

getContentResolver().notifyChange(uri, null);

This approach is a good example of the Observer Pattern of object-oriented design.

ptc
  • 536
  • 6
  • 9
  • 11
    Ok, and in which way `DatasetObserver` differs from `ContentProvider`? – pixel Apr 13 '11 at 13:47
  • 13
    I haven't used a `DataSetObserver`, but it seems from the documentation (http://developer.android.com/reference/android/database/DataSetObserver.html) a `DataSetObserver` is notified of cursor lifecycle changes such as closing and requerying, whereas `ContentObserver` is used to watch for changes in underlying data. Hope that helps. – ptc Apr 13 '11 at 17:10
  • 7
    Now I see. `DatasetObserver` observes `Cursor` state, whereas `ContentProvider` observes underlying content changes. Thanks! – pixel Apr 13 '11 at 17:56
  • 1
    `requery()` is now deprecated, has the method for doing this changed? – Andrew Wyld Mar 18 '13 at 14:45
  • 1
    Using managedQuery is also deprecated. The currently recommended approach is to asynchronously query your ContentProvider with CursorLoaders. They observe changes and automatically requery their cursors. See this: http://stackoverflow.com/questions/7182920/what-are-the-benefits-of-cursorloaders – ptc Mar 19 '13 at 15:05
6

I'm not sure if this question is still on anyone's radar. I have been struggling with the same question for a little while now. What I came up with as my litmus test for deciding whether to use a DataSet Observer or a ContentObserver is pretty straight-forward:

If I need to send a URI in my notification I use a ContentObserver. If I simply need to notify one object that another object has changed -- I use a DataSetObserver.

The delimiting factor, for me at least, is does the object that is sending out the notification expose it's underlying resources (be they objects, records, queries, or cursors) as "Universal Resource Identifiers" to the rest of the application; or does the object hide the source of its data.

Charles Thomas
  • 855
  • 10
  • 11
2

To provide the supplement to ptc's answer, DataSetObserver is used for handling content changes in the Adapter, for example, it can be used for updating listview dynamically with Adapter. You can register a DataSetObserver using the Adapter#registerDataSetObserver() method.

DataSetObserver can also be used to observe the content changes in the Cursor in a similar fashion.

Community
  • 1
  • 1
Yogesh Umesh Vaity
  • 16,749
  • 10
  • 82
  • 69
1

From my last app developed I can say. The main difference between ContentObserver and DataSetObserver, is that ContentObserver makes to Observer any change affects on ContentProvider. On the other hand, DataSetObserver Observer any change effect on the database.

IgorGanapolsky
  • 23,124
  • 17
  • 109
  • 132
devqmr
  • 493
  • 5
  • 15