我想要以下行为:
observableMain
应缓冲所有项目,直到observableResumed
发出值。然后observableMain
应该发出所有缓冲的和所有特征值......
我在activity's
onCreate
中做了什么:
PublishSubject<T> subject = ...; // I create a subject to emit items to and to subscribe to
// 1) I create a main observable from my subject
final Observable<T> observableMain = subject
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
// 2) I use a custom base class in which I can register listeners
// for the onResume event and which I can query the isResumed state!
// I call the object the pauseResumeProvider!
// 2.1) I create an observable, it emits a value ONLY if my activity is resumed
final Observable<Boolean> obsIsResumed = Observable
.defer(() -> Observable.just(pauseResumeProvider.isActivityResumed()))
.skipWhile(aBoolean -> aBoolean != true);
// 2.2) I create a second observable, it emits a value as soon as my activity is resumed
final Observable<Boolean> obsOnResumed = Observable.create(new Observable.OnSubscribe<Boolean>()
{
@Override
public void call(final Subscriber<? super Boolean> subscriber)
{
pauseResumeProvider.addPauseResumeListener(new IPauseResumeListener() {
@Override
public void onResume() {
pauseResumeProvider.removePauseResumeListener(this);
subscriber.onNext(true);
subscriber.onCompleted();
}
@Override
public void onPause() {
}
});
}
});
// 2.3) I combine the resumed observables and only emit the FIRST value I can get
final Observable<Boolean> observableResumed = Observable
.concat(obsIsResumed, obsOnResumed)
.first();
// 3) here I'm stuck
// 3 - Variant 1:
Observable<T> observable = observableMain
.buffer(observableResumed)
.concatMap(values -> Observable.from(values));
// 3 - Variant 2:
// Observable<T> observable = observableMain.delay(t -> observableResumed);
// 4) I emit events to my my subject...
// this event is LOST!
subject.onNext("Test in onCreate");
问题
恢复subject
后发送到activity
的所有项目都在运行,之前的所有项目都将丢失(至少使用delay
解决方案)。我无法达到理想的行为。我该如何正确解决这个问题?
答案 0 :(得分:5)
重播源并使用delaySubscription触发真实订阅。
PublishSubject<Integer> emitNow = PublishSubject.create();
ConnectableObservable<T> co = source.replay();
co.subscribe();
co.connect();
co.delaySubscription(emitNow).subscribe(...);
emitNow.onNext(1);
修改强>
Here is a gist使用操作符lift
进入可以暂停和恢复上游排放的序列。
答案 1 :(得分:0)
另一种方法是延迟源(热)可观察的排放,直到“阀门”打开
source.delay(new Func1<Integer, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(Integer integer) {
return valve.filter(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean isOpen) {
//emits only when isOpen is true
return isOpen;
}
});
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("out: " + integer);
}
});
要点:Rx Valve