我正在尝试实现一个在后台线程上运行的DBService类,它有一个方法Observable getWhere(@NonNull RealmQuery realmQuery)。我知道我需要在同一个线程上创建Realm实例,我才能访问它。所以,我找到了一种在后台线程上创建RealmQuery的方法,但它是一个可怕的黑客。我的所有其他尝试都产生了java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created
演示者代码:
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()返回我唯一的后台线程。
DBService:
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));
});
}
我尝试了其他方法,但我总是收到来自错误线程的Realm访问权限。
虽然我的解决方案有效但是,它可以冻结我的应用程序一段时间,直到创建了realmQuery,这是我想要避免的。有什么建议?提前谢谢。
答案 0 :(得分:1)
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());