Realm.getInstance(context)
restituirà raramente un'istanza di dominio già chiusa. Com'è possibile?Android: Realm.getInstance (contesto) restituisce un'istanza di dominio già chiusa
Sto usando Reame con RxJava, per https://realm.io/news/using-realm-with-rxjava/
In particolare, questo metodo genera un IllegalStateException: This Realm instance has already been closed, making it unusable.
@Override
public void call(final Subscriber<? super RealmList<T>> subscriber) {
final Realm realm = Realm.getInstance(context);
subscriber.add(Subscriptions.create(new Action0() {
@Override
public void call() {
try {
realm.close();
} catch (RealmException ex) {
subscriber.onError(ex);
}
}
}));
RealmList<T> object;
realm.beginTransaction(); //THROWS EXCEPTION
//...
}
Se commento fuori la questione realm.close();
, nessun problema. Anche se penso che questo porterà a una perdita di memoria nativa, quindi.
La mia ipotesi migliore sul motivo per cui questo si sta verificando è che sono state fatte più chiamate a questo metodo e se questo metodo chiama perfettamente la linea, un'istanza di dominio già chiusa può essere recuperata?
MODIFICA: utilizzando Schedulers.io()
, vengono visualizzati molti avvisi Calling close() on a Realm that is already closed
. La mia ipotesi è che in qualche modo dopo aver finito di usare il thread .io()
, l'istanza del reame si chiude automaticamente. Non sono sicuro del perché questo potrebbe accadere però.
EDIT2: Passando all'utilizzo di Schedulers.newThread()
anziché Schedulers.io()
per i miei osservabili, il problema si è interrotto. Ma vedo un sacco di avvisi Remember to call close() on all Realm instances
. Sono abbastanza sicuro che li sto chiudendo, quindi sono molto confuso su questo.
EDIT3: passando all'utilizzo di AndroidSchedulers.mainThread()
, nessun errore. Tranne che le chiamate del mio reame sono eseguite sul thread principale, il che è un brutto male. La mia ipotesi sul perché questo non causa alcun avvertimento è perché il realm
ora vive sul thread principale, che è anche il punto in cui viene chiamato realm.close()
(tramite il rx.subscriber
).
EDIT4: Ecco la logica per la mia chiamata osservabile nel regno.
@Override
public Observable<List<ImageArticleCategoryEntity>> getArticleBuckets() {
return RealmObservable.list(context, GET_ARTICLE_BUCKETS)
.filter(FILTER_OUT_NULL_OR_EMPTY_LIST)
.switchIfEmpty(refreshAndSaveAndLoadNewDataFromDb)
.map(CONVERT_FROM_REALMLIST_TO_IMAGE_ARTICLE_ENTITYLIST);
}
public void loadArticleImages() {
articleRepo.getArticleBuckets()
.subscribeOn(RealmThread.get())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<ImageArticleCategoryEntity>>() {
@Override
public void onCompleted() {
Timber.v("Loading article images complete!");
if (view != null)
view.hideLoadingAnimation();
}
@Override
public void onError(Throwable e) {
Timber.e("Error loading article images", e);
Log.e("tag", "Error loading article images", e);
if (view != null) {
view.hideLoadingAnimation();
view.showLoadingErrorToast();
}
}
@Override
public void onNext(List<ImageArticleCategoryEntity> integerImageArticleCategoryEntityHashMap) {
if (view != null)
view.loadArticleImages(integerImageArticleCategoryEntityHashMap);
}
});
sei sicuro al 100% che 'Realm.getInstance (context)' restituisca effettivamente un'istanza chiusa? Penso che dovresti probabilmente associare il Realm al conteggio delle attività in un servizio, o al ciclo di vita di un'attività, o al ciclo di vita di un frammento senza testa conservato. – EpicPandaForce
Non eseguo operazioni IO sul thread principale, che sembra essere ciò che si suggerisce, poiché le istanze di autenticazione non possono essere passate attraverso i thread. Sì, sono sicuro al 100% che ciò accada. Ho provato un blocco try/catch che ha rilevato 'IllegalStateException'. Nel catch, ho ottenuto un nuovo 'realm' tramite' realm.getInstance (context) 'e ho chiamato' realm.beginTransaction() 'immediatamente dopo. Ha gettato di nuovo l'eccezione. – ZakTaccardi
oh, va bene. non è possibile condividere il dominio attraverso il thread. – EpicPandaForce