Kotlin Can';t在dispose()之后使用相同的DisposableObserver和subscribeWith两次
代码(Kotlin)非常简单,但我不明白,为什么不能再次使用相同的对象订阅Kotlin Can';t在dispose()之后使用相同的DisposableObserver和subscribeWith两次,kotlin,rx-java2,Kotlin,Rx Java2,代码(Kotlin)非常简单,但我不明白,为什么不能再次使用相同的对象订阅 val x = Observable.interval(1L, TimeUnit.SECONDS, Schedulers.io()) .map { println("emitting=$it") it.toString() }.publish().autoConnect() val o = object : DisposableObserver<String>
val x = Observable.interval(1L, TimeUnit.SECONDS, Schedulers.io())
.map {
println("emitting=$it")
it.toString()
}.publish().autoConnect()
val o = object : DisposableObserver<String>() {
override fun onComplete() {}
override fun onNext(t: String) = println("O:=$t")
override fun onError(e: Throwable) {}
}
println("---------- subscribe ----------")
val s2 = x.subscribeWith(o)
sleepSeconds(2)
println("---------- dispose ----------")
s2.dispose()
sleepSeconds(2)
println("---------- subscribe again ----------")
x.subscribeWith(o) //<<-- This doesn't work!!!!
sleepSeconds(5)
当我创建类DisposableObserver的新实例时,它工作得很好
DisposableObserver
设计为只能订阅一次。当您在DisposableObserver的引擎盖下查看时,您将看到AtomicReference上游
,它在observer订阅时保存了当前的DisposableObserver
public abstract class DisposableObserver<T> implements Observer<T>, Disposable {
final AtomicReference<Disposable> upstream = new AtomicReference<Disposable>();
@Override
public final void onSubscribe(@NonNull Disposable d) {
if (EndConsumerHelper.setOnce(this.upstream, d, getClass())) {
onStart();
}
}
// rest of code
这就是为什么您不能使用相同的DisposableObserver实例重新订阅,但可以使用新实例
public abstract class DisposableObserver<T> implements Observer<T>, Disposable {
final AtomicReference<Disposable> upstream = new AtomicReference<Disposable>();
@Override
public final void onSubscribe(@NonNull Disposable d) {
if (EndConsumerHelper.setOnce(this.upstream, d, getClass())) {
onStart();
}
}
// rest of code
public static boolean setOnce(AtomicReference<Disposable> upstream, Disposable next, Class<?> observer) {
ObjectHelper.requireNonNull(next, "next is null");
if (!upstream.compareAndSet(null, next)) {
next.dispose(); // dispose next if there is set upstream previously
if (upstream.get() != DisposableHelper.DISPOSED) {
reportDoubleSubscription(observer);
}
return false;
}
return true;
}