How to Close() all the instances of the Realm before deleting its file

Viewed 3285

I got the java.lang.IllegalStateException while trying to delete the realm file.

java.lang.IllegalStateException: It's not allowed to delete the file associated with an open Realm. Remember to close() all the instances of the Realm before deleting its file: /data/data/com.mypackage.name/files/filename.realm

I used both executeTransactionAsync and executeTransaction method. So, I guess that there is an instance async that I can not close it before delete the whole realm file.

How can I close all the instances of realm or how to delete realm file without getting this exception?

2 Answers

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 Realms 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
    }
}
Related