我仍在尝试将RXJava 2用于多个订阅者使用的轮询服务。除了它总是被调用两次之外它运作良好。
我尝试使用publish(1),take(1),share(),refCount()等,但结果总是一样的。叫两次或多次。
我仍然不明白为什么它被召唤两次。新订阅者应该接收最新发布的值,并且仅在更改后的值(如果更改了hashmap)返回为修改后的列表。
我的民意调查(单身人士)
public Observable<List<Light>> lightPolling = CallFactory
.with(context)
.getLights(MainApplication.lastaccespoint)
.repeatWhen(o -> o.concatMap((Function<Object, ObservableSource<?>>) v -> Observable.timer(1000, TimeUnit.MILLISECONDS)))
.filter(new MapPredicate<>())
.distinctUntilChanged()
.map(l -> {
List<Light> lights = new ArrayList<>();
for (Map.Entry<String, Light> entry : l.entrySet()) {
Light light = entry.getValue();
light.setId(entry.getKey());
lights.add(light);
}
return lights;
})
// .replay(1)
// .distinct()
//.publish()
//.share()
.compose(ReplayingShare.instance()); // its like .share(), just including the last result etc.
如果哈希映射真的发生了变化,我的Predicate用于过滤。 StringUtil.equalMap只是一个比较两个效果良好的哈希图的简单方法。
class MapPredicate<T> implements Predicate<Map<String, T>> {
private Map<String, T> lastMap;
@Override
public boolean test(Map<String, T> map) throws Exception {
if (!StringHelper.equalMap(map, lastMap)) {
Timber.d("Result in MapPredicate doesnt equals last result");
lastMap = map;
return false;
}
return true;
}
}
最后我的Disposable订阅了Observable。
lightsDisposable = LightManager
.getInstance(context)
.lightPolling
.subscribeWith(new BulbsObserver());
更多用于测试
LightManager.getInstance(context).lightPolling.debounce(10, TimeUnit.SECONDS).subscribe(lights -> Timber.d("Received light second Subscriber "+ lights.size()));
LightManager.getInstance(context).lightPolling.debounce(15, TimeUnit.SECONDS).subscribe(lights -> Timber.d("Received light Third Subscriber "+ lights.size()));
当然是我的观察员
private class BulbsObserver extends DisposableObserver<List<Light>> {
@Override
public void onNext(List<Light> newLights) {
Timber.d("Received lights=" + newLights.size());
lights.clear();
lights.addAll(newLights);
adapter.notifyDataSetChanged();
}
@Override
public void onError(Throwable throwable) {
Timber.e(throwable);
}
@Override
public void onComplete() {
Timber.d("onComplete called");
}
}
答案 0 :(得分:4)
refCount()
订阅(调用subscribe函数),并在最后一个订阅者离开后取消订阅。如果您的订阅者按顺序进行(即引用计数在它们之间降至零),您将遇到对原始源的多个订阅/取消订阅。
如果您只想订阅一次且从不取消订阅,请使用autoConnect()
代替refCount()
。例如:
hotObservable = coldObservable.replay(1).autoConnect();