2017-01-03 1 views
0

Прежде всего я управлять экземпляр области действия по Repository класса:Этот экземпляр Realm уже закрыт, что делает его непригодным для использования + 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); 
} 
} 

И единственный класс, который простирается от этого RealmRepository, это мой класс контроллера. Проблема заключается в том, когда я делаю в первый раз выполнить метод в моем фрагменте я получил:

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

Но после этой ошибки, если перезагрузка фрагмента все работает нормально. И прежде, чем этот первый фрагмент выполнит метод вызова из классов Services и работает хорошо. Например: Этот метод отлично работает, даже если выполнить его первый:

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

Но это один бросает исключение:

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

ответ

2

экземпляры Realm являются подсчет ссылок после первого вызова инициализации. Каждый вызов функции close() уменьшает этот счетчик ссылок, и каждый вызов метода getDefaultInstance() увеличивает этот счетчик ссылок. Ресурсы Realm освобождаются после того, как счетчик ссылок достигает 0.

Учитывая тот факт, что вы используете блокировку для блокировки доступа к вашему экземпляру Realm, вы вызываете, чтобы число ссылок достигало 0 при вызове close() , а затем не повторно инициализировать конфигурацию Realm после того, как Realm уже освободил свои ресурсы.

Чтобы исправить это, вам необходимо, чтобы ваши вызовы getDefaultInstance() перекрывались перед последующим вызовом, чтобы закрыть(), чтобы гарантировать, что счетчик ссылок останется> 0, пока вы все еще активно используете Realm, в противном случае вам нужно повторно инициализировать всю конфигурацию Realm каждый раз, когда это будет сопровождаться воздействием производительности.

+0

как я могу отслеживать, что остается = 0? – Drake

+0

Напишите класс RealmWrapper: P – Submersed

+0

@Submersed Вы на 100% уверены в своем заключении? Я просто не могу поверить, что нулевые ссылки заставляют Realm закрываться до следующего вызова init(). Да, это может привести к очистке всех кэшированных данных, но вызов getDefaultInstance() должен снова инициализировать его сам, не так ли? – skywall

1

Метод finally будет выполнен до того, как метод вызова получит результат в этом случае.

Смежные вопросы