Область закрыта ошибка в обратном вызове onSuccess executeTransactionAsync - PullRequest
0 голосов
/ 25 февраля 2019

Я начал получать новые ошибки в своем последнем выпуске, которых я никогда раньше не видел, в коде, который не редактировался в течение многих месяцев.

Неустранимое исключение: java.lang.IllegalStateException ThisЭкземпляр области уже закрыт, что делает его непригодным для использования.

У меня есть вызовы API, которые получают данные, а затем записывают содержимое в Realm в методе 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 область должна быть закрыта, но иногда происходит сбой вобратный вызов onSuccess для запроса области в getLocalGroups (realm)

Этот код был таким уже довольно давно, и теперь это происходит и в другом месте, поэтому я не понимаю, что изменилось (я обновил сборку Android)инструменты ??) но также это неправильно, действительно ли область близка в onSuccess?

Зачем закрывать царство, если я все еще пытаюсь использовать ресурсы?

Это приложение в настоящее время доступно в Realm 4.4 и уже давно.Мы еще не успели сделать обновление до 5 из-за серьезных изменений.

1 Ответ

0 голосов
/ 26 февраля 2019

Вам повезло, что этого не произошло, пытались ли вы выйти из приложения, пока выполнялся этот запрос?;)

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 немедленно закрывает область, не дожидаясь завершения асинхронной транзакции, и, очевидно, область, которую вы «открыли» (увеличенный локальный счетчик экземпляров), былазакрыто во время транзакции записи.

Удивительно, что вы получили 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() {
                        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");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...