OK, so this won't really solve the problem (but it will at least try to close Realms on main thread), but will allow you to debug why and where you opened a Realm that wasn't closed.
Just get an instance of TraceableRealm.getInstance(realmConfig, "I needed it for that tiny query")
and close TraceableRealm
instance instead of just Realm
.
Inside realmIndex
you will get a list of still open Realm
s together with threads and reasons for their existence...
class TraceableRealm(
val realm: Realm,
val thread: String,
val purpose: String
): Closeable
{
companion object {
val realmIndex = mutableListOf<TraceableRealm>()
fun getInstance(config: RealmConfiguration, purpose: String): TraceableRealm {
val newRealm = TraceableRealm(Realm.getInstance(config), Thread.currentThread().name, purpose)
realmIndex.add(newRealm)
realmIndex.removeAll { !it.isOpen }
return newRealm
}
fun killZombies() {
runUI {
realmIndex.filter { it.isOpen && it.thread == Thread.currentThread().name }.forEach {
try {
it.close()
} catch (ex: Exception) {
Timber.d("Problem removing zombie realm: $it")
}
}
realmIndex.removeAll { !it.isOpen }
realmIndex.forEach {
Timber.d("Couldn't close realm: $it")
}
}
}
}
var isOpen = true
override fun toString(): String {
return "$purpose in $thread open=$isOpen"
}
override fun close() {
realm.close()
isOpen = false
}
}