阅读了Realm的文档(这是非常好的,赞成之后),到目前为止我想到的是:
findAllAsync()
或其他类似的方法,这些方法在UI线程上执行查询并将结果返回到UI线程现在我的问题不仅仅是“我不想在UI线程中查询”。我希望能够在我创建的处理程序线程中查询域,将结果Observable
与在同一处理程序线程上运行的其他处理器Observable
链接起来,最后将处理结果传递给UI线程。主要是因为UI线程的处理过于昂贵。
基本上这样的片段看起来像这样:
Observable
.defer(new Func0<Observable<RealmResults<User>>>() {
@Override
public Observable<RealmResults<User>> call() {
Realm realm = Realm.getDefaultInstance();
return realm.where(User.class).findAll().asObservable();
}
})
.map(new Func1<RealmResults<User>, UserUIData>() {
@Override
public UserUIData call(RealmResults<User> users) {
return new UserUIData(users.first());
}
})
.subscribeOn(MY_HANDLER_THREAD_SCHEDULER)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
到目前为止我遇到的两个问题:
当我取消订阅UI线程时,应用程序会崩溃,因为根据RealmObservableFactory
,当取消订阅时,必须在UI线程中删除更改侦听器。在我看来,我们无法改变执行以下哪个调度程序,而且Realm不允许跨线程进行访问/修改,因此崩溃。
subscriber.add(Subscriptions.create(new Action0() {
@Override
public void call() {
realm.removeChangeListener(listener);
}
}));
我无法找到正确关闭Realm
实例的方法。
有人可以帮我指点正确的方向吗?我不应该首先这样做吗?还有更好的方法吗?
非常感谢。
答案 0 :(得分:3)
您应该可以使用unsubscribeOn
/ doOnUnsubscribe
这样的组合(未经测试):
AtomReference<Realm> realmRef = new AtomicReference(null);
Observable
.defer(new Func0<Observable<RealmResults<User>>>() {
@Override
public Observable<RealmResults<User>> call() {
Realm realm = Realm.getDefaultInstance();
realmRef.set(realm);
return realm.where(User.class).findAll().asObservable();
}
})
// ...
.doOnOnsubscribe(realmRef.get().close())
.unsubscribeOn(MY_HANDLER_THREAD_SCHEDULER)
.subscribeOn(MY_HANDLER_THREAD_SCHEDULER)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
我们在此处遇到一个问题,即可以更轻松地跨线程移动RealmQueries。一旦实现,应该更好地处理这种情况:https://github.com/realm/realm-java/issues/1955