Java 在后台线程上创建RealmQuery
我试图实现一个在后台线程上运行的DBService类,它有一个可观察的getWhere(@NonNull RealmQuery RealmQuery)方法。正如我所知,我需要在访问它的同一线程上创建领域实例。因此,我找到了一种在后台线程上创建RealmQuery的方法,但这是一种可怕的攻击。我所有的其他尝试都导致了Java 在后台线程上创建RealmQuery,java,android,multithreading,realm,Java,Android,Multithreading,Realm,我试图实现一个在后台线程上运行的DBService类,它有一个可观察的getWhere(@NonNull RealmQuery RealmQuery)方法。正如我所知,我需要在访问它的同一线程上创建领域实例。因此,我找到了一种在后台线程上创建RealmQuery的方法,但这是一种可怕的攻击。我所有的其他尝试都导致了java.lang.IllegalStateException:从错误线程访问领域。领域对象只能在创建它们的线程上访问 演示者代码: dataUseCase.searchDisk(ge
java.lang.IllegalStateException:从错误线程访问领域。领域对象只能在创建它们的线程上访问
演示者代码:
dataUseCase.searchDisk(getRealmQuery(RepoRealm.class)
.equalTo("owner.login", userLogin), RepoRealm.class)
public static getRealmQuery RealmQuery(Class clazz) { // horrible hack
if (handler == null)
handler = new Handler(getHandlerThread().getLooper());
handler.postAtFrontOfQueue(() -> realmQuery = RealmQuery.createQuery(Realm.getDefaultInstance(), clazz));
while (true) if (realmQuery != null) break;
return realmQuery;
}
getHandlerThread().getLooper()返回我唯一的后台线程
数据库服务:
public Observable<List> getWhere(@NonNull RealmQuery realmQuery) {
return Observable.defer(() -> {
Realm realm = Realm.getDefaultInstance();
return realmQuery.findAll().asObservable()
.filter(results -> ((RealmResults) results).isLoaded())
.map(o -> realm.copyFromRealm((RealmResults) o))
.doOnUnsubscribe(() -> closeRealm(realm));
});
}
公共可观测getWhere(@NonNull RealmQuery RealmQuery){
返回可观察。延迟(()->{
Realm Realm=Realm.getDefaultInstance();
返回realmQuery.findAll().asObservable()
.filter(结果->((RealmResults)结果).isLoaded())
.map(o->realm.copyFromRealm((RealmResults)o))
.dounsubscribe(()->closeRealm(realm));
});
}
我尝试了其他方法,但我总是收到来自错误线程的领域访问异常
虽然我的解决方案可以工作,但它可以冻结我的应用程序一段时间,直到创建realmQuery,这是我想要避免的。有什么建议吗?提前感谢。公共可观察的getWhere(RealmQueryProvider queryFactory){
public <T extends RealmModel> Observable<List<T>> getWhere(RealmQueryProvider<T> queryFactory) {
return Observable.defer(() -> {
Realm realm = Realm.getDefaultInstance();
return queryFactory.create(realm).asObservable()
.filter(results -> ((RealmResults<T>) results).isLoaded())
.map(o -> realm.copyFromRealm((RealmResults<T>) o))
.doOnUnsubscribe(() -> closeRealm(realm));
});
}
public interface RealmQueryProvider<T extends RealmModel> {
RealmResults<T> create(Realm realm);
}
// example
Observable<List<Dog>> dogs = dbService.getWhere((realm) -> realm.where(Dog.class).findAll());
返回可观察。延迟(()->{
Realm Realm=Realm.getDefaultInstance();
返回queryFactory.create(realm.asObservable())
.filter(结果->((RealmResults)结果).isLoaded())
.map(o->realm.copyFromRealm((RealmResults)o))
.dounsubscribe(()->closeRealm(realm));
});
}
公共接口RealmQueryProvider{
RealmResults创建(领域领域);
}
//范例
可观察的dogs=dbService.getWhere((realm)->realm.where(Dog.class.findAll());
是的,不要使用handler.postafrontofqueue)
并跨线程抛出随机领域管理的对象,特别是如果您使用的是RxJava,它已经有了observeOn(AndroidSchedulers.mainThread())
这与p.S做的事情完全相同。为了回答这个问题,您正在打开一个从未关闭过的新领域实例,它需要知道您如何处理从Realm获得的RealmResults
。我只想在后台线程上创建一个Realm实例,并将其传递给主线程以创建一个Realm查询
您不能在线程之间传递Realm实例。我已经更新了我的问题并添加了DBService方法的实现。我还没有关闭那个领域实例吗?这段代码没有编译。queryFactory.create(realm).asObservable()create(realm)没有asObservable as method应该是我的示例所示的结果是的,我发现了这一点。我试过了,效果很好。但我面临一个性能问题。它冻结了我的UIThread,但我仍在检查它是否是其他的东西我假设它是其他的东西。除非您的GC出于好奇而运行,否则这是什么计划程序?