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

Функция fetchData находится во фрагменте. Класс dataRepository содержит функцию, которую я использую для извлечения данных с диска:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_user, container, false);

    realm = Realm.getDefaultInstance();

    Log.i("realm", "oncreateView");

    items = new ArrayList<>();

    try {
        Log.i("realm", "check" + (realm == null));
    } catch (Exception e) {
        e.printStackTrace();
    }

    fetchData();

    return view;
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (realm != null && !realm.isClosed())
        realm.close();
    Log.i("realm", "ondestroy");
}

    private void fetchData() {

    abcDataRepository = DataRepository.getInstance(realm);

    Observable<List<User>> observable = bcDataRepository.getUser_List();

    observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(Users-> {
                Log.i("data", Users.size() + "");

                for (int i = 0; i < Users.size(); i++) {
                    items.add(Users.get(i));
                }
            });
}

Класс DataRepository:

public class DataRepository {

    private Realm realm;

private static PoliticoDataRepository dataRepository = null;

private PoliticoDataRepository(Realm realm) {
    this.realm = realm;
}

public static PoliticoDataRepository getInstance(Realm realm) {
    if (dataRepository == null)
        dataRepository = new PoliticoDataRepository(realm);

    return dataRepository;
}

@Override
public Observable<List<User>> getUser_List() {

    final UserDiskData diskData = new UserDiskData(realm);

    if (diskData.User_Size() > 0) {
        return diskData.getUser_List();
    } else {
        final UserCloudData cloudData = new UserCloudData(realm);
        return cloudData.getUser_List();
    }
}
}

Класс UserDiskData:

class  UserDiskData {

private Realm realm;

UserDiskData(Realm realm) {
    this.realm = realm;
}

int User_Size() {
    final RealmResults<User> results = realm.where(User.class).findAll();
    Log.i("disk", "pulledData" + results.size());
    return results.size();
}

@Override
public Observable<List<User>> getUser_List() {

    Log.i("disk", "called");

    final RealmResults<User> results = realm.where(User.class).findAll();
    ArrayList<User> list = new ArrayList<>();
    for (int i = 0; i < results.size(); i++)
        list.add(results.get(i));

    return Observable.just(list);
}

}

В первый раз приложение работает нормально, но когда я выхожу из приложения и открываю его снова, оно вылетает и выдает ошибку This Realm instance has already been closed, что делает его непригодным для использования. Он отлично работает, если я пропущу realm.close в конце. Должен ли я вручную закрыть объект области, если да, то как? По какой-то причине realm==null возвращает true, когда я закрываю приложение и открываю его снова, почему оно это делает, особенно учитывая, что realm.getdefaultinstance вызывается прямо перед ним.


person Jude Fernandes    schedule 05.02.2017    source источник
comment
переместить close() в onDestroyView()   -  person EpicPandaForce    schedule 06.02.2017
comment
@EpicPandaForce, который не работал, oncreateView вызывается каждый раз, когда приложение открывается, поэтому realm = Realm.getDefaultInstance(); выполняется, но по какой-то причине область по-прежнему остается нулевой.   -  person Jude Fernandes    schedule 06.02.2017
comment
Ответ, кажется, здесь: github.com/realm/realm-java/ вопросы/4149#issuecomment-277949679   -  person Christian Melchior    schedule 08.02.2017


Ответы (1)


Мой коллега @zaki50 отмечает:

DataRepository сохраняет статическую ссылку на PoliticoDataRepository. Это означает, что DataRepository.getInstance(Realm realm) может вернуть старый экземпляр PoliticoDataRepository, который содержит закрытый экземпляр Realm.

Вы должны удалить статическое поле и убедиться, что DataRepository.getInstance(Realm realm) всегда возвращает экземпляр, который ссылается на переданный экземпляр Realm.

person G. Blake Meike    schedule 08.02.2017