Закрыть экземпляр Realm после завершения выполнения

android realm

1742 просмотра

4 ответа

919 Репутация автора

Я хочу закрыть свой экземпляр Realm executeTransactionAsyncпосле завершения выполнения. Причина в том, что основной поток моих приложений продолжает зависать, я думаю, причина в том, что экземпляр фоновой области не закрывается после завершения выполнения. Смотрите мой код ниже:

realm.executeTransactionAsync(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        // Execute realm code
                        realm.copyToRealmOrUpdate(myData);
                        // Can I close the realm instance here without getting an 
                        // error? realm.close(); causes an error.
                    }
                }, new Realm.Transaction.OnSuccess() {
                    @Override
                    public void onSuccess() {
                        Log.i("CB", "success");
                        // looks like I cannot access the execute Realm 
                        // instance here.
                        // Closing realm.getDefaultInstance does not change my issue
                    }
                }, new Realm.Transaction.OnError() {
                    @Override
                    public void onError(Throwable error) {
                        Log.i("CB", "error - " + error.getMessage());
                    }
                });
            }

Пожалуйста, смотрите мои комментарии. Мой экран приложения просто становится черным. Выполнение завершается успешно и onSuccess()вызывается, но я не могу получить доступ к executeэкземпляру области, чтобы закрыть его отсюда.

Есть ли у вас какие-либо предложения относительно того, что я могу попробовать? Я делаю что-то неправильно?

Заранее спасибо.

РЕДАКТИРОВАТЬ

07-19 11:43:42.379 8146-8146/com.shortterminsurance.shortterm I/CB: success
07-19 11:43:43.258 8146-8152/com.shortterminsurance.shortterm W/art: Suspending all threads took: 33.234ms
07-19 11:43:43.266 8146-8156/com.shortterminsurance.shortterm I/art: Background partial concurrent mark sweep GC freed 476307(17MB) AllocSpace objects, 512(10MB) LOS objects, 40% free, 33MB/55MB, paused 7.261ms total 163.497ms
07-19 11:43:44.131 8146-8156/com.shortterminsurance.shortterm I/art: Background sticky concurrent mark sweep GC freed 408160(9MB) AllocSpace objects, 459(15MB) LOS objects, 35% free, 35MB/55MB, paused 10.287ms total 147.823ms
07-19 11:43:44.834 8146-8152/com.shortterminsurance.shortterm W/art: Suspending all threads took: 103.676ms
07-19 11:43:44.848 8146-8156/com.shortterminsurance.shortterm W/art: Suspending all threads took: 13.424ms

Это мой logcat после вызова onSuccess. Я думаю, что фоновый экземпляр области executeпродолжает работать по какой-то причине :(.

Автор: Lunchbox Источник Размещён: 19.07.2016 09:22

Ответы (4)


1 плюс

87 Репутация автора

Как сказал Тим Кастелийнс, executeTransactionAsync уже закрывает область, в любом случае, закрытие экземпляра области не приводит к блокировке пользовательского интерфейса, но выдает исключение, если вы пытаетесь открыть экземпляр Realm, поэтому у вас должна быть другая проблема.

Автор: MikeOx Размещён: 19.07.2016 09:35

3 плюса

56115 Репутация автора

Это возможность:

            final Realm realm = Realm.getDefaultInstance();
            realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    // Execute realm code
                    realm.copyToRealmOrUpdate(myData);
                }
            }, new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    Log.i("CB", "success");
                    realm.close();
                }
            }, new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable error) {
                    Log.i("CB", "error - " + error.getMessage());
                    realm.close();
                }
            });
        }

Хотя экземпляр фоновой области закрывается автоматически.

Автор: EpicPandaForce Размещён: 19.07.2016 09:37

10 плюса

33296 Репутация автора

Решение

Экземпляр области, который передается здесь

@Override
public void execute(Realm realm) {

закрыто для вас. Вам не нужно беспокоиться о закрытии самостоятельно.

Если вы проверите исходный код для Realm.executeTransactionAsync (), вы можете найти

bgRealm.beginTransaction();
try {
    transaction.execute(bgRealm);

    if (!Thread.currentThread().isInterrupted()) {
        bgRealm.commitTransaction(false, new Runnable() {
            @Override
            public void run() {
                // The bgRealm needs to be closed before post event to caller's handler to avoid
                // concurrency problem. eg.: User wants to delete Realm in the callbacks.
                // This will close Realm before sending REALM_CHANGED.
                bgRealm.close();
            }
        });
        transactionCommitted = true;
    }
}
...

Итак, сначала он вызывает .execute()вашу транзакцию, а после этого закрывает экземпляр области, который он передал вам.

Автор: Tim Castelijns Размещён: 19.07.2016 09:38

1 плюс

36 Репутация автора

final Realm realmFirstInstance = Realm.getDefaultInstance();
realmFirstInstance.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                // Execute realm code
                realm.copyToRealmOrUpdate(myData);
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                Log.i("CB", "success");
                realmFirstInstance.close();
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(Throwable error) {
                Log.i("CB", "error - " + error.getMessage());
                realmFirstInstance.close();
            }
        });
    }

Кроме того, для более ясного понимания: не забудьте закрыть первый экземпляр области. Потому что здесь «realmFirstInstance» и «realm» внутри метода execute () - это два разных объекта.

Автор: Svyatoslav Ruzhitsky Размещён: 10.07.2019 10:41
Вопросы из категории :
32x32