[英]Transform RealmResult in same background thread with RxJava
我正在使用RxJava + Realm,并且想做一些看起来很简单的事情:
我想加载所有符合特定条件的RealmObject,转换每个RealmResult对象,然后在这些转换对象准备好后通知主线程。 我需要转换在后台线程中进行的原因,并且如果RealmResults中有大量对象,这是一个长期运行的操作
问题是,我能够在后台加载对象,但是在仍处于后台线程中时无法对每个对象执行任何操作。 我也试图以一种被动的方式做到这一点。
到目前为止的代码:
groupContactSubscription = realm.where(GroupContact.class)
.equalTo(MODEL_ID, mGroupId)
.findAllAsync()
.asObservable()
.filter(new Func1<RealmResults<GroupContact>, Boolean>() {
@Override
public Boolean call(RealmResults<GroupContact> groupContacts) {
return groupContacts.isLoaded();
}
})
.first()
.map(new Func1<RealmResults<GroupContact>, List<Contact>>() {
@Override
public List<Contact> call(RealmResults<GroupContact> groupContacts) {
List<Contact> contacts = new ArrayList<>();
//Transform each GroupContact
for(int i=0; i<groupContacts.size(); ++i){
contacts.add(transformGroupContact(groupContacts.get(0))
}
return contacts;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<Contact>>() {
@Override
public void call(List<Contact> contacts) {
// Deal with transformed objects
}
});
问题是,这不会在后台线程中发生(它仍会阻塞主线程)。
我不太确定该怎么做,有人可以指出我已经存在的问题的正确方向吗? 我认为正在发生的事情是Realm事务异步发生,并且filter-> map也正在同一后台线程上发生。 显然,事实并非如此。
这是我尝试使用RxJava的尝试,请保持友好
groupContactSubscription = Observable.fromCallable(() -> {
try(Realm realm = Realm.getDefaultInstance()) {
RealmRefresh.refreshRealm(realm); // from http://stackoverflow.com/a/38839808/2413303
RealmResults<GroupContact> groupContacts = realm.where(GroupContact.class)
.equalTo(MODEL_ID, mGroupId)
.findAll();
List<Contact> contacts = new ArrayList<>();
//Transform each GroupContact
for(int i = 0; i < groupContacts.size(); ++i) {
contacts.add(transformGroupContact(groupContacts.get(i));
}
return contacts;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<Contact>>() {
@Override
public void call(List<Contact> contacts) {
// Deal with transformed objects
}
});
尽管这不会自动更新,所以我对此不太了解,但我认为这会起作用:
groupContactSubscription = realm.where(GroupContacts.class).findAll().asObservable()
.observeOn(Schedulers.io())
.switchMap(() ->
Observable.fromCallable(() -> {
try(Realm realm = Realm.getDefaultInstance()) {
RealmRefresh.refreshRealm(realm); // from http://stackoverflow.com/a/38839808/2413303
RealmResults<GroupContact> groupContacts = realm.where(GroupContact.class)
.equalTo(MODEL_ID, mGroupId)
.findAll();
List<Contact> contacts = new ArrayList<>();
//Transform each GroupContact
for(int i = 0; i < groupContacts.size(); ++i) {
contacts.add(transformGroupContact(groupContacts.get(i));
}
return contacts;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<Contact>>() {
@Override
public void call(List<Contact> contacts) {
// Deal with transformed objects
}
});
尽管使用正确的Realm模式 ,您甚至不需要进行此类转换(这会导致急切地评估整个数据库,将延迟加载窗口抛出),您只需执行
Subscription contacts = realm.where(Contact.class)
.equalTo("groupContact.modelId", mGroupId)
.findAllAsync()
.asObservable()
.filter(RealmResults::isLoaded)
.filter(RealmResults::isValid)
.subscribe(...);
或类似的东西。 也许只是按原样返回GroupContact
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.