When should I call realm.close()?

realm.close() is used when you are done with your current schema. In Realm api page it says the following:

close(): Closes this Realm so it may be re-opened with a newer schema version. All objects and collections from this Realm are no longer valid after calling this method.

If you don't want to change your schema, you don't have to worry about close method.

Full reference here: Realm close method.


some good, and straight-to-the-point references:

  • https://realm.io/docs/kotlin/latest/#closing-realms
  • https://realm.io/docs/kotlin/latest/#default-realm
  • https://medium.com/@Zhuinden/how-to-use-realm-for-android-like-a-champ-and-how-to-tell-if-youre-doing-it-wrong-ac4f66b7f149#1888

Realm instances are reference counted—if you call getInstance twice in a thread, you need to call close twice as well. This allows you to implement Runnable classes without having to worry about which thread will execute them: simply start it with getInstance and end it with close.

when executing transactions (generally in background threads):

  1. obtain a Realm instance
  2. used in an executeTransaction
  3. then, immediately close() afterwards

for example:

Realm.getDefaultInstance()

    // use will close realm after the transaction is finished/failed
    .use { realm ->

        // DO NOT execute read/write operations outside of a transaction...
        // because it will lead to stale reads, exceptions, and other problems

        realm.executeTransaction { realm ->
            // do things in the transaction (both reading & writing)
        }
    }

On the main/UI/looper/handler threads, keep an instance of Realm open, because you're usually interested in listening to changes in RealmResults obtained from that Realm instance:

  1. a Realm instance is created/obtained when the application is visible
  2. the instance is shared by all operations executed on the main thread (typically read operations)
  3. upon application shutdown, the shared instance is close()d.

for example:

// in chronological order....on main UI thread

// application starts....
val realm = Realm.getDefaultInstance()

// user navigating to some view...

// execute a query that will return results that we're interested in displaying
val realmResults = realm.where(Entity::class.java).findAllAsync()

// need to hold a strong reference to the listener, otherwise it may stop 
// receiving callbacks from Realm, because Realm only holds weak references to 
// registered listeners
val listener = RealmChangeListener<RealmResults<Entity>> { assessments ->
    // update UI
}

// add the listener to the query
realmResults.addChangeListener(listener)

// user shutting down app...close main thread's realm
realm.close()