我在DataManager中创建一个方法,首先从缓存中下载数据,然后从服务器API请求数据,保存结果并将网络数据发送给演示者(在MVP中)。
问题是,当我想在后台进行操作时,使用Realm会在UI线程上进行。我发现了一些关于第一个RxJava的域支持的文章,但我们正在使用另一个具有另一个API的版本,所以这些Realm方法对我们没有帮助(toObservable())。
如何解决问题?
此外,正如我所看到的,所有其他方法都在IO线程上处理,只有Realm在Ui上工作,无论我放置subscribeOn(Schedulers.io())
的事实。为什么会这样?
@Override
public Observable<ChatsRepoAnswerModel> getChats() {
return getChatsFromCache(STATUS_OK)
.subscribeOn(Schedulers.io())
.mergeWith(
getChatsService()
.getChats()
.subscribeOn(Schedulers.io())
.map(ChatResponseModel::getResult)
.flatMap(mChatsMapper::transformAll)
.doOnNext(this::saveChats)
.doOnNext(Collections::sort)
.onErrorResumeNext(getChatsFromCache(STATUS_ERROR))
.observeOn(AndroidSchedulers.mainThread());
}
private void saveChats(List<ChatDataModel> realmObjects) {
Realm.getDefaultInstance().executeTransaction(realm -> {
realm.insertOrUpdate(realmObjects);
});
}
private Observable<ChatsRepoAnswerModel> getChatsFromCache(int aStatus) {
Realm realm = Realm.getDefaultInstance();
RealmResults<ChatDataModel> chats = realm.where(ChatDataModel.class).findAll();
return processChatResponse(realm.copyFromRealm(chats), aStatus);
}
答案 0 :(得分:1)
我认为这完全无视Realm试图给你的零拷贝设计:
RealmResults
形式提供的自动更新和被动数据集的单向数据流(意味着您会在数据时收到通知设置更改)RealmResults
只是一个“光标”,RealmObject
仅在调用访问者时读取数据< / LI>
这很有趣,因为realm.copyFromRealm()
创建了非托管对象,通常没有这些属性:
无论如何,在后台线程上创建分离的RealmObjects的解决方案是在该线程上打开实例,复制数据集,然后关闭实例。
Observable.fromCallable(() -> { // <-- defer to whatever thread you're running it on
try(Realm realm = Realm.getDefaultInstance()) {
return realm.copyFromRealm(realm.where(Cat.class).findAll());
} // <-- auto-close
})
.subscribeOn(Schedulers.whatever());
通常,按照预期使用Realm更容易,尤其是对于更大的数据集。