IllegalStateException:不允许删除与打开的领域关联的文件

IllegalStateException: It's not allowed to delete the file associated with an open Realm

我在调用 Realm.deleteRealm(config) 时出现异常:

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

我在 Application.onCreate 中的 Realm.init() 之后调用它,因此没有理由打开其他实例。

public void onCreate() {
    Realm.init(this);

    Realm realm;
    RealmConfiguration config = getConfig();
    try {
        realm = Realm.getInstance(config); // Will migrate if needed
    } 
    catch (RealmMigrationNeededException e) 
    {
        Realm.deleteRealm(config);
        realm = Realm.getInstance(config);
    }
}

我看到了这些主题,但看不到解决方案:

https://github.com/realm/realm-java/issues/4552

https://github.com/realm/realm-java/issues/5416

编辑:

我认为我的问题是当我重新启动应用程序以尝试失败迁移时。在应用程序中,我打开了但没有关闭的实例,并且无法轻易关闭它们,代码太复杂了。当我重新启动应用程序以通过向模型添加字段来测试迁移异常时,可能有一些实例是从上次启动时打开的。

编辑 2:

我试图回到领域 3.0.0(我以前的版本),但我没有这个 IllegalStateException。我目前使用的是 4.2.0。

也许我在更新日志中遗漏了一些东西..

您可以使用

public void onCreate() {
    Realm.init(this);

    Realm realm;
    RealmConfiguration config = getConfig();
    try {
        realm = Realm.getInstance(config); // Will migrate if needed
    } 
    catch (RealmMigrationNeededException e) 
    {
        realm.close();
        Realm.deleteRealm(config);
        realm = Realm.getInstance(config);
    }
}

而不是

public void onCreate() {
        Realm.init(this);

        Realm realm;
        RealmConfiguration config = getConfig();
        try {
            realm = Realm.getInstance(config); // Will migrate if needed
        } 
        catch (RealmMigrationNeededException e) 
        {
            Realm.deleteRealm(config);
            realm = Realm.getInstance(config);
        }
    }

我从这个话题得到了答案: https://github.com/realm/realm-java/issues/4552

如果您知道从版本 N 迁移到版本 N+1 会抛出此 IllegalStateException,您可以使用 DynamicRealm 检查版本并在需要时删除 Realm。

主题中有更多详细信息。

在删除领域配置之前添加以下行。

realm.close();

realm-java4.1.0之前,Realm.deleteRealm()不是进程安全的调用。这意味着如果在其他进程中打开了 Realm 实例,它不会抛出。但是在 Realm 实例打开时删除将有很大的机会破坏数据库文件。

4.1.0开始,Realm.deleteRealm()是多进程安全的API。如果它检测到在其他 processes/threads.

上打开了 Realm 实例,它将抛出

因此请检查您是否正在其他进程中使用 Realm,并且在调用 deleteRealm().

之前这些进程没有正确关闭