我有一个列表想要每分钟刷新一次。 例如,用户列表在此处:https://github.com/android10/Android-CleanArchitecture/blob/master/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java
我使用repeatWhen添加定期刷新:
public Observable<List<User>> buildUseCaseObservable(Void unused) {
return this.userRepository
.users()
.repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Observable<Object> objectObservable) throws Exception {
return objectObservable.delay(1, TimeUnit.MINUTES);
}
});
}
这样工作正常,每分钟调用onNext。 但是,如果我想立即刷新此列表(由于用户的操作或因为通知),我不知道如何执行此操作。
我应该取消/处置observable并重启一个新的吗? 感谢
答案 0 :(得分:2)
从您的代码中我了解用户列表是在订阅时生成和发出的。
以下是我能想到的一些解决方案,而不是取消订阅和重新订阅您想立即做出反应的事件:
不使用repeatWhen
运算符,而是使用interval
creation operator与flatMap
结合使用,每分钟调用一个新的Observable订阅并使用merge
运算符以添加对您感兴趣的其他事件的反应。像这样:
@Test
public void intervalObservableAndImmediateReaction() throws InterruptedException {
Observable<String> obs = Observable.interval(1, TimeUnit.SECONDS)
.cast(Object.class)
.mergeWith(
Observable.just("mockedUserClick")
.delay(500, TimeUnit.MILLISECONDS))
.flatMap(
timeOrClick -> Observable.just("Generated upon subscription")
);
obs.subscribe(System.out::println);
Thread.currentThread().sleep(3000); //to see the prints before ending the test
}
或根据您的需要进行调整(但校长相同):
Observable.interval(1, TimeUnit.MINUTES)
.mergeWith(RxView.clicks(buttonView))
.flatMap(timeOrClick -> this.userRepository.users());
您可以像以前一样使用flatMap
运算符,即使在保持当前实现工作且不合并间隔的情况下 - 只需保留您的工作代码,并将其保存在程序链的另一个区域中{您选择的{3}}:
RxView.touches(yourViewVariable)
.flatMatp(motionEvent -> this.userRepository.users())
.subscribe(theObserver);
请注意,在此解决方案中,订阅是独立于两个可观察者完成的。如果您使用不同的观察者,或者管理该主题或某事物,您可能会更好。我运行的一个小测试表明,一个订阅者处理了订阅2个不同的observable而没有问题(在Rxjava1中 - 还没有检查Rxjava2),但是对我来说感觉不错。
答案 1 :(得分:1)
如果您不关心在其他一个可观察数据发出数据后调整刷新时间,您可以执行以下操作:
// Specific example of a user manually requesting
val request = Observable.create<String> { emitter ->
refresh.setOnClickListener {
emitter.onNext("Click Request")
}
}
.observeOn(Schedulers.io())
.flatMap {
userRepository.users()
}
// Refresh based off of your original work, could use something like interval as well
val interval = userRepository.users()
.subscribeOn(Schedulers.io())
.repeatWhen { objectObservable ->
objectObservable.delay(1, TimeUnit.MINUTES)
}
// Combine them so that both emissions are received you can even add on another source
Observable.merge(request,interval)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
contents.text = it.toString()
}, {
contents.text = it.toString()
},{
println(contents.text)
})
然后您不必每次都处置和重新订阅