背景
我在我的应用程序中使用 Realm。当数据加载完毕后,会进行密集处理,因此处理过程发生在后台线程。
所使用的编码模式是工作单元模式,而 Realm 仅存在于 DataManager 下的存储库中。这里的想法是每个存储库可以有不同的数据库/文件存储解决方案。
我尝试的方法
以下是类似于我在 FooRespository 类中所拥有代码的示例。
这里的想法是获取一个 Realm 实例,用于查询感兴趣的对象的 Realm,将它们返回并关闭 Realm 实例。请注意,这是同步的,并且最后将对象从 Realm 复制到未管理的状态。
public Observable<List<Foo>> getFoosById(List<String> fooIds) {
Realm realm = Realm.getInstance(fooRealmConfiguration);
RealmQuery<Foo> findFoosByIdQuery = realm.where(Foo.class);
for(String id : fooIds) {
findFoosByIdQuery.equalTo(Foo.FOO_ID_FIELD_NAME, id);
findFoosByIdQuery.or();
}
return findFoosByIdQuery
.findAll()
.asObservable()
.doOnUnsubscribe(realm::close)
.filter(RealmResults::isLoaded)
.flatMap(foos -> Observable.just(new ArrayList<>(realm.copyFromRealm(foos))));
}
这段代码随后会与通过RxJava进行的重型处理代码一起使用:
dataManager.getFoosById(foo)
.flatMap(this::processtheFoosInALongRunningProcess)
.subscribeOn(Schedulers.io()) //could be Schedulers.computation() etc
.subscribe(tileChannelSubscriber);
阅读文档后,我相信上述内容应该可以工作,因为它不是异步的,因此不需要循环线程。我在同一线程内获取了realm实例,因此它没有在线程之间传递,对象也没有被传递。
问题是,当执行上述操作时,我得到了“从错误的线程访问Realm。只能在创建它们的线程上访问Realm对象。”这似乎不正确。我唯一能想到的是,Realm实例池正在为我提供使用主线程创建的另一个进程中创建的现有实例。
Schedulers.io
对吗?可能像这样:.flatMap(this::processtheFoosInALongRunningProcess) .subscribeOn(Schedulers.io()) //也可以是 Schedulers.computation() 等等 .subscribe(tileChannelSubscriber);``` 语法方面不太确定。
- wint.findFoosByIdQuery.equalTo(Foo.FOO_ID_FIELD_NAME, id); .findAll() .asObservable() .flatMap(this::processtheFoosInALongRunningProcess) .subscribeOn(Schedulers.io()) //可能是 Schedulers.computation() 等 .subscribe(tileChannelSubscriber);```
- wintcopyFromRealm
会将 RealmObject 从底层 Realm 中分离出来,而非受线程限制的未受管控副本。 - EpicPandaForce正如我们所讨论的,这会破坏Realms的零拷贝和一致性保证,但同时也能够支持目前Realm不支持的架构模式。
是的,没错。 - EpicPandaForce