4

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?

NamNH
  • 1,752
  • 1
  • 15
  • 37

2 Answers2

1

Hard to answer without some more details, as open instances can come from a lot of places. Perhaps the two links below can provide some guidance in how you work with the Realm instances:

See https://realm.io/docs/java/latest/#closing-realms and https://realm.io/docs/java/latest/#realm-instance-lifecycle

Christian Melchior
  • 19,978
  • 5
  • 62
  • 53
  • Thanks for your response. That same with what I was thought. Just a question that why `Realm` can get the count of realm instances via `getLocgealInstanceCount` or `getGlobalInstanceCount` instances, but not get the list of instances? Or not a native function that stop and close all realm instances. – NamNH Nov 14 '17 at 08:01
  • We could make a `forceClose` method, but that would most likely just end up crashing some other part of your app, which is why we haven't added it. – Christian Melchior Nov 14 '17 at 08:08
  • I see. With my limited knowledge, I found on the source that `executeTransactionAsync` make a new `RealmAsyncTask` and with any pending transaction Realm will create a new `bgRealm` instance. Though it can be closed after `submitTransaction`, but if it's in transaction, I can not stop all instances manually so that I can not delete realm file. – NamNH Nov 14 '17 at 09:21
  • You can register an `onSuccess` listener on close the Realm instance when it returns? – Christian Melchior Nov 14 '17 at 09:38
  • @ChristianMelchior Need suggestions using Realm with CleanArchitecture, tried posting it on Reddit, but it got removed automatically, SO will probably mark it as opinion based, where should I ask? – Sarthak Mittal Nov 14 '17 at 12:32
0

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
    }
}
ssuukk
  • 8,200
  • 7
  • 35
  • 47