我当前的Android项目在Firebase实时数据库中保存了不同类型的参考数据。
Android应用程序拥有自己的此参考数据的本地副本,必须根据上次更新日期刷新。
我希望使用RxJava来并行控制刷新此引用数据。
成功刷新所有参考数据后,我希望将本地的上次更新日期重置为今天。
我目前的解决方案并没有按照预期行事。我无法重置上次更新日期以等待成功刷新参考数据。
我的代码目前类似于: -
Observable.just(Boolean.TRUE)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.doOnNext(refresh -> referenceTypeA())
.doOnNext(refresh -> referenceTypeB())
.doOnNext(refresh -> referenceTypeC())
.doOnNext(refresh -> recordTodaysDate())
.subscribe();
每个referenceTypeX()
方法都具有以下相同的结构: -
private void referenceTypeX() {
firebaseService
.getReferenceTypeX()
.doAfterSuccess(this::referenceTypeX)
.doOnError(this::processError)
.subscribe();
}
public Single<List<ReferenceTypeX>> getReferenceTypeX() {
return Single.create(emitter ->
mReferenceTypeXDatabaseReference
.orderByChild("typeXKey")
.addValueEventListener(buildTypeXListener(emitter)));
}
这就是问题所在,因为Firebase回调在主线程上运行,而一些参考数据有1000行,我在后台线程上处理数据更改事件,如下所示: -
public class TypeXListener extends BaseValueEventListener<List<ReferenceTypeX>> {
private static final TypeXMapper TYPE_X_MAPPER = Selma.builder(TypeXMapper.class).build();
private static final List<ReferenceTypeX> TYPE_X = new ArrayList<>();
public TypeXListener(final SingleEmitter<List<ReferenceTypeX>> emitter) {
super(emitter);
}
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
final GenericTypeIndicator<TypeXCsv> typeXTypeIndicator = new GenericTypeIndicator<TypeXCsv>() {
};
final Thread thread = new Thread(() -> {
for (final DataSnapshot typeXDataSnapshot : dataSnapshot.getChildren()) {
final TypeXCsv typeXCsv = typeXDataSnapshot.getValue(typeXDataSnapshot);
final TypeX typeX = TypeXMapper.mapTypeX(typeXCsv);
TYPE_X_s.add(typeX);
}
emitter.onSuccess(TYPE_X_s);
});
thread.start();
}
}
我相信我需要为每个referenceTypeX()
方法创建一个Observable并将它们传递给我的Observable.just()
然后使用flatMap()来并行化参考数据更新。
我如何实现这一目标?
特别是当我需要firebase实时回调在后台线程而不是主线程上运行时?
我相信我的解决方案类似于
Observable.just(referenceTypeA(), referenceTypeB(), referenceTypeC())
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.flatMap(?????????????)
.doOnComplete(recordTodaysDate())
.subscribe();
答案 0 :(得分:1)
您需要修改referenceTypeX()
函数,以便它们不在函数中订阅:
private Single<List<ReferenceTypeX>> referenceTypeX() {
return firebaseService
.getReferenceTypeX()
.doAfterSuccess(this::referenceTypeX)
.doOnError(this::processError)
.subscribe(); // <-- remove this, just return
}
然后,您可以通过组合这些函数来构建主要的observable:
Single
.zip(
referenceTypeA().subscribeOn(Schedulers.io()),
referenceTypeB().subscribeOn(Schedulers.io()),
referenceTypeC().subscribeOn(Schedulers.io()),
Function3<A,B,C,Result> { combineIntoResult(...) })
.flatMap(???) // is this necessary?
.map(recordTodaysDate())
.subscribe();