【问题标题】:Realm is closed error within onSuccess callback of executeTransactionAsync领域在 executeTransactionAsync 的 onSuccess 回调中关闭错误
【发布时间】:2019-02-26 07:11:20
【问题描述】:

在我的上一个版本中,我开始遇到以前从未见过的新错误,这些错误出现在几个月未编辑的代码上。

致命异常:java.lang.IllegalStateException 这个 Realm 实例 已经关闭,无法使用。

我有获取数据的 API 调用,然后在 executeTransactionAsync 方法中将内容写入领域,然后在 onSuccess 中查询领域中所有在回调中返回的记录(可能还有其他记录)。

api().getLocalGroups(1).enqueue(new Callback<LocalGroupBase>() {
            @Override
            public void onResponse(@NonNull Call<LocalGroupBase> call, @NonNull final Response<LocalGroupBase> response) {

                try (Realm realm = setupRealm(context)) {
                    realm.executeTransactionAsync(new Realm.Transaction() {
                        @Override
                        public void execute(@NonNull Realm realm) {
                            realm.copyToRealmOrUpdate(response.body().getResults());
                        }
                    }, new Realm.Transaction.OnSuccess() {
                        @Override
                        public void onSuccess() {
                            callback.onLoaded(LocalGroup.getLocalGroups(realm));
                        }
                    });
                }
            }

            @Override
            public void onFailure(@NonNull Call<LocalGroupBase> call, Throwable t) {
                callback.onError(t.getMessage());
            }
        });


public static RealmResults<LocalGroup> getLocalGroups(Realm realm) {
        return realm.where(LocalGroup.class).findAllSorted("name");
    }

它使用资源的 try,所以在 try 语句完成后,领域应该被关闭,但它偶尔会在 getLocalGroups(realm) 中领域查询的 onSuccess 回调中崩溃

这段代码已经有很长一段时间了,现在也发生在另一个地方,所以我对发生了什么变化感到困惑(我更新了 Android 构建工具??)但这也是错误的,领域实际上是否接近- 可以在 onSuccess 内吗?

如果我还在尝试资源,为什么要关闭领域?

这个应用程序目前在 Realm 4.4 上并且已经存在了很长时间。由于一些重大更改,我们还没有时间升级到 5。

【问题讨论】:

    标签: android realm


    【解决方案1】:

    您很幸运没有发生这种情况,您是否尝试在此请求进行时退出应用程序? ;)

    try (Realm realm = setupRealm(context)) { // <-- opens Realm
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(@NonNull Realm realm) {
                ... // <-- runs in background asynchronously for some time
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                callback.onLoaded(LocalGroup.getLocalGroups(realm)); // <-- runs after background async transaction is complete
            }
        });
    } // <-- closes Realm
    

    因此,try-finally 会立即关闭 Realm,而无需等待异步事务完成,显然您“打开”的 Realm(增加的本地实例计数)在写入事务期间已关闭。

    令人惊讶的是,您收到onSuccess 回调但 Realm 已关闭,我认为 Realm 在这种情况下吞下了回调...

    唉,您的解决方案的 hack-fix 将是:

    api().getLocalGroups(1).enqueue(new Callback<LocalGroupBase>() {
            @Override
            public void onResponse(@NonNull Call<LocalGroupBase> call, @NonNull final Response<LocalGroupBase> response) {
    
                try (Realm realm = setupRealm(context)) {
                    realm.executeTransactionAsync(new Realm.Transaction() {
                        @Override
                        public void execute(@NonNull Realm realm) {
                            realm.copyToRealmOrUpdate(response.body().getResults());
                        }
                    }, new Realm.Transaction.OnSuccess() {
                        @Override
                        public void onSuccess() {
                            try(Realm r = Realm.getDefaultInstance()) {
                                callback.onLoaded(LocalGroup.getLocalGroups(r));
                            }
                        }
                    });
                }
            }
    
            @Override
            public void onFailure(@NonNull Call<LocalGroupBase> call, Throwable t) {
                callback.onError(t.getMessage());
            }
        });
    
    
    public static RealmResults<LocalGroup> getLocalGroups(Realm realm) {
        return realm.where(LocalGroup.class).findAllSorted("name");
    }
    

    【讨论】:

    • 谢谢!!为什么这只是现在才开始破裂呢?这个代码库在我加入之前就有几十个这样的用法,这些用法已经有一年多了,而且我只是在我做的最后一个版本中才开始看到错误,而且这种情况很少见。我实际上像你一样早早地解决了一个只是解释了但与尝试/资源无关......但由于某种原因,我没有看到这个相同。在下一个版本中,我会接到很多更新的电话......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多