Navigation

React to Changes - Android SDK

You can register a notification handler on an entire realm. Realm Database calls the notification handler whenever any write transaction involving that realm is committed. The handler receives no information about the change.

This is useful when you want to know that there has been a change but do not care to know specifically what changed. For example, proof of concept apps often use this notification type and simply refresh the entire UI when anything changes. As the app becomes more sophisticated and performance-sensitive, the app developers shift to more granular notifications.

Example

Suppose you are writing a real-time collaborative app. To give the sense that your app is buzzing with collaborative activity, you want to have an indicator that lights up when any change is made. In that case, a realm notification handler would be a great way to drive the code that controls the indicator. The following code shows how to observe a realm for changes with with addChangeListener():

class MyActivity : Activity() {
private lateinit var realm: Realm
private lateinit var realmListener: RealmChangeListener<Realm>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
realm = Realm.getDefaultInstance()
realmListener = RealmChangeListener {
// ... do something with the updates (UI, etc.) ...
}
// Observe realm notifications.
realm.addChangeListener(realmListener)
}
override fun onDestroy() {
super.onDestroy()
// Remove the listener.
realm.removeChangeListener(realmListener)
// Close the Realm instance.
realm.close()
}
}
Important
Automatic Refresh

All threads that contain a Looper automatically refresh RealmObject and RealmResult instances when new changes are written to the realm. As a result, it isn't necessary to fetch those objects again when reacting to a RealmChangeListener, since those objects are already updated and ready to be redrawn to the screen.

You can register a notification handler on a specific collection within a realm. The handler receives a description of changes since the last notification. Specifically, this description consists of three lists of indices:

  • The indices of the objects that were deleted.
  • The indices of the objects that were inserted.
  • The indices of the objects that were modified.
Important
Order Matters

In collection notification handlers, always apply changes in the following order: deletions, insertions, then modifications. Handling insertions before deletions may result in unexpected behavior.

Realm Database emits an initial notification after retrieving the collection. After that, Realm Database delivers collection notifications asynchronously whenever a write transaction adds, changes, or removes objects in the collection.

Unlike realm notifications, collection notifications contain detailed information about the change. This enables sophisticated and selective reactions to changes. Collection notifications provide all the information needed to manage a list or other view that represents the collection in the UI.

Example

The following code shows how to observe a collection for changes with addChangeListener():

val dogs = realm.where(Dog::class.java).findAll()
// Set up the collection notification handler.
val changeListener =
OrderedRealmCollectionChangeListener { collection: RealmResults<Dog>?, changeSet: OrderedCollectionChangeSet ->
// For deletions, notify the UI in reverse order if removing elements the UI
val deletions = changeSet.deletionRanges
for (i in deletions.indices.reversed()) {
val range = deletions[i]
Log.v("EXAMPLE", "${range.length} dogs deleted at ${range.startIndex}")
}
val insertions = changeSet.insertionRanges
for (range in insertions) {
Log.v("EXAMPLE", "${range.length} dogs inserted at ${range.startIndex}")
}
val modifications = changeSet.changeRanges
for (range in modifications) {
Log.v("EXAMPLE", "${range.length} dogs modified at ${range.startIndex}")
}
}
// Observe collection notifications.
dogs.addChangeListener(changeListener)

You can register a notification handler on a specific object within a realm. Realm Database notifies your handler:

  • When the object is deleted.
  • When any of the object's properties change.

The handler receives information about what fields changed and whether the object was deleted.

Example

The following code shows how create a new instance of a class in a realm and observe that instance for changes with addChangeListener():

// Create a dog in the realm.
var dog = Dog()
realm.executeTransaction { transactionRealm ->
dog = transactionRealm.createObject(Dog::class.java, ObjectId())
dog.name = "Max"
}
// Set up the listener.
val listener = RealmObjectChangeListener { changedDog: Dog?, changeSet: ObjectChangeSet? ->
if (changeSet!!.isDeleted) {
Log.i("EXAMPLE", "The dog was deleted")
} else {
for (fieldName in changeSet.changedFields) {
Log.i(
"EXAMPLE",
"Field '$fieldName' changed."
)
}
}
}
// Observe object notifications.
dog.addChangeListener(listener)
// Update the dog to see the effect.
realm.executeTransaction { r: Realm? ->
dog.name = "Wolfie" // -> "Field 'name' was changed."
}

You can unregister a change listener by passing your change listener to Realm.removeChangeListener(). You can unregister all change listeners currently subscribed to changes in a realm or any of its linked objects or collections with Realm.removeAllChangeListeners().

Give Feedback