我是RxJava的新手,所以我希望有更多知识的人可以撕掉我从RealmResults获取Flowable的方法,在Flowable的生命周期内维护对资源的引用,然后处理它在末尾。我有兴趣知道我做的任何错误。这背后的动机是能够订阅实时领域查询而不将Realm暴露给应用程序的其余部分。 我不太热衷的一件事是,Realm实例被传递给函数,然后Flowable管理关闭它,而不是调用者管理关闭它,但我看不到关闭Realm实例的方法调用类没有保持对它的单独引用或将整个事物包装在另一个看起来有点难看的Flowable.using中。
public class RxRealm {
private static class ResultsResource<T extends RealmModel> {
final Realm realm;
final RealmResults<T> results;
ResultsResource(Realm realm, RealmResults<T> results) {
this.realm = realm;
this.results = results;
}
}
public static <T extends RealmModel> Flowable<RealmResults<T>> asFlowable(final Realm realm, final RealmResults<T> results) {
return Flowable.using(new Callable<ResultsResource>() {
@Override
public ResultsResource call() throws Exception {
return new ResultsResource<>(realm, results);
}
}, new Function<ResultsResource, Publisher<? extends RealmResults<T>>>() {
@Override
public Publisher<? extends RealmResults<T>> apply(@NonNull ResultsResource resultsResource) throws Exception {
return Flowable.create(new FlowableOnSubscribe<RealmResults<T>>() {
@Override
public void subscribe(@NonNull final FlowableEmitter<RealmResults<T>> emitter) throws Exception {
final RealmChangeListener<RealmResults<T>> changeListener = new RealmChangeListener<RealmResults<T>>() {
@Override
public void onChange(RealmResults<T> element) {
if (!emitter.isCancelled()) {
emitter.onNext(element);
}
}
};
results.addChangeListener(changeListener);
}
}, BackpressureStrategy.LATEST);
}
}, new Consumer<ResultsResource>() {
@Override
public void accept(@NonNull ResultsResource resource) throws Exception {
resource.results.removeAllChangeListeners();
resource.realm.close();
}
});
}
}
用法:
public Flowable<Integer> getUnreadMessages(final String matchingId) {
Realm realm = Realm.getDefaultInstance();
RealmQuery<Message> query = realm.where(Message.class)
.equalTo("read", false);
if (matchingId != null) {
query.equalTo("id", matchingId);
}
RealmResults<Message> results = query.findAllAsync();
return RxRealm.asFlowable(realm, results)
.map(new Function<RealmResults<Message>, Integer>() {
@Override
public Integer apply(@NonNull RealmResults<Message> realmResults) throws Exception {
return realmResults.size();
}
});
}