2017-01-03 3 views
0

Zu allererst machen i Reich Instanz von Repository-Klasse verwalten:Diese Realm Instanz bereits geschlossen wurde, ist es unbrauchbar + RxJava

public class RealmRepository { 

private Lock lock; 

protected RealmRepository() { 
    lock = new ReentrantLock(); 
} 

public <T> T execute(Executor<T> executor) { 
    Realm realm = null; 
    try { 
     lock.lock(); 
     realm = Realm.getDefaultInstance(); 
     return executor.execute(realm); 
    } finally { 
     if (realm != null && !realm.isClosed()) { 
      realm.close(); 
     } 
     lock.unlock(); 
    } 
} 

public interface Executor<T> { 
    T execute(Realm realm); 
} 
} 

Und die einzige Klasse, die von diesem RealmRepository erstreckt, dies ist mein Controller-Klasse ist. Problem ist, wenn ich zum ersten Mal Methode in meinem Fragmente fahre ich bekam:

java.lang.IllegalStateException: Dieses Realm Beispiel wurde bereits geschlossen, es unbrauchbar zu machen.

Aber nach diesem Fehler, wenn neu laden Fragment funktioniert alles in Ordnung. Und vor diesem ersten Fragment führen Sie Methoden aus, die von Services-Klassen aufrufen, und funktioniert gut. Zum Beispiel: Diese Methode funktioniert perfekt, auch wenn es zuerst ausführen:

public Observable<ModuleRealm> getModule(String moduleTitle) { 
    return execute(realm -> realm.where(ModuleRealm.class) 
      .equalTo("code", moduleTitle) 
      .findAllAsync() 
      .asObservable() 
      .first() 
      .map(RealmResults::first)); 
} 

Aber diese löst eine Ausnahme:

public Observable<List<ProductCategoryRealm>> getProductCategories() { 
    return execute(realm -> realm.where(ProductCategoryRealm.class) 
      .findAll() 
      .asObservable() 
      .first() 
      .map(realm::copyFromRealm)); 
} 

Antwort

2

Realm Instanzen sind Referenz nach dem ersten Initialisierungsaufruf gezählt. Jeder Aufruf von close() verringert diesen Verweiszähler, und jeder Aufruf von getDefaultInstance() erhöht diesen Verweiszähler. Die Ressourcen des Bereichs werden freigegeben, sobald der Referenzzähler 0 erreicht.

Angesichts der Tatsache, dass Sie Sperren verwenden, um Zugriffe auf Ihre Realm-Instanz zu blockieren, verursachen Sie, dass der Referenzzähler 0 erreicht, wenn Sie Ihren close() -Aufruf ausführen , dann wird die Realm-Konfiguration nicht erneut initialisiert, nachdem Realm bereits seine Ressourcen freigegeben hat.

Um dies zu beheben, müssen Sie Ihre Aufrufe von getDefaultInstance() vor dem nachfolgenden Aufruf von close() überlappen, um sicherzustellen, dass Ihr Referenzzähler> 0 bleibt, während Sie noch aktiv Realm verwenden, anderenfalls müssen Sie reinitialize die gesamte Realm-Konfiguration jedes Mal, die mit einer Leistung Auswirkungen kommen wird.

+0

Wie kann ich das zurückbleiben = 0? – Drake

+0

Schreiben Sie eine RealmWrapper-Klasse: P – Submersed

+0

@Submersed Sind Sie 100% sicher über Ihre Schlussfolgerung? Ich kann einfach nicht glauben, dass Null-Referenzen Realm bis zum nächsten Aufruf von init() geschlossen haben. Ja, es kann alle zwischengespeicherten Daten löschen, aber das Aufrufen von getDefaultInstance() sollte es erneut selbst initiieren, nicht wahr? – skywall

1

Die Methode finally wird ausgeführt, bevor die aufrufende Methode in diesem Fall das Ergebnis erhält.

Verwandte Themen