我尝试使用realm作为API下载数据的持久化方法。我收到错误:*
引起:java.lang.IllegalStateException:此Realm实例具有 已关闭,使其无法使用。
我不知道我对持久性方法做错了什么。我的坚持下课是下一个:
public class PersistenceManager {
@Inject
public PersistenceManager(){}
public void saveHabitants(final List<Habitant> habitants){
Realm realm = Realm.getDefaultInstance(); // opens db
try {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insertOrUpdate(habitants);
}
});
} finally {
realm.close();
}
}
public void saveHabitant(final Habitant habitant){
Realm realm = Realm.getDefaultInstance();
try {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insertOrUpdate(habitant);
}
});
} finally {
realm.close();
}
}
public List<Habitant> loadHabitants(){
Realm realm = Realm.getDefaultInstance();
List<Habitant> results;
try {
results = realm.where(Habitant.class).findAll();
} finally {
realm.close();
}
return results;
}
public List<Habitant> loadHabitants(int indexFrom, int limit){
Realm realm = Realm.getDefaultInstance();
List<Habitant> results;
try {
results = realm.where(Habitant.class).findAll();
results.subList(indexFrom, limit);
} finally {
realm.close();
}
return results;
}
public Habitant loadHabitant(long id){
Realm realm = Realm.getDefaultInstance();
Habitant result;
try {
result = realm.where(Habitant.class).equalTo("id", id).findFirst();
} finally {
realm.close();
}
return result;
}
}
当我使用方法loadHabitants(int indexFrom, int limit)
时,我收到此错误。
答案 0 :(得分:1)
只要在给定线程上至少有一个打开的Realm实例,就可以通过延迟加载(每个访问器)访问RealmResults。
我其实打算参考文档,但由于某些原因我无法找到它?无论如何,懒惰地访问RealmResults,因此当没有打开的Realm实例时,它变得无效,并且无法再访问。对于RealmObjects也是如此。
The docs请说:
...通过惰性缓存访问RealmObjects和RealmResults ...
因此,如果关闭与之关联的线程本地Realm实例,则无法返回托管的RealmResults,并期望它保持打开状态。
两种解决方案:
1。)参考关于如何在UI线程和后台线程上正确管理Realm生命周期的documentation
2。)使用realm.copyFromRealm()
,它急切地评估整个数据集,创建它的分离副本。请注意,这不是免费操作,如果在UI线程上使用copyFromRealm()
,较大的数据集很容易导致UI线程冻结。
public List<Habitant> loadHabitants(int indexFrom, int limit){
try(Realm realm = Realm.getDefaultInstance()) {
List<Habitant> results = realm.where(Habitant.class).findAll();
results = new ArrayList<>(results.subList(indexFrom, limit));
for(int i = 0, size = results.size(); i < size; i++) {
results.set(i, realm.copyFromRealm(results.get(i)));
}
return Collections.unmodifiableList(results);
}
}