Observable发布数据并由Observer消费。消费者应该有一个可以放弃操作资源的能力,Disposable的设计在于解耦,而状态管理是针对Observer端的,所以在实现Observer时顺带实现Disposable接口,这样消费端便具备了状态管理的能力。单单具备这个能力还不够,还需要Observable的配合。
@CheckReturnValue
@SchedulerSupport("none")
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {
ObjectHelper.requireNonNull(onNext, "onNext is null");
ObjectHelper.requireNonNull(onError, "onError is null");
ObjectHelper.requireNonNull(onComplete, "onComplete is null");
LambdaObserver<T> ls = new LambdaObserver(onNext, onError, onComplete, Functions.emptyConsumer());
this.subscribe((Observer)ls);
return ls;
}
关注Observable核心方法,可以看到,方法返回一个Disposable,Observer会作为Disposable的角色返回,并被我们程序得到,进而我们能够对Observer的状态进行控制。
//状态管理接口,非函数式接口,无法通过函数式的方式来快速使用该接口。
public interface Disposable {
void dispose();
boolean isDisposed();
}
接下来看ObservableCache#subscribeActual(Observer<? super T> t)的实现:
protected void subscribeActual(Observer<? super T> t) {
ObservableCache.CacheDisposable<T> consumer = new ObservableCache.CacheDisposable(t, this);
t.onSubscribe(consumer);
this.add(consumer);
//首次订阅,这个方法将订阅者和ObservableCache建立联系,实际调用的就是ObservableCache,于是可以将Observer和ObservableCache分开控制状态。
if (!this.once.get() && this.once.compareAndSet(false, true)) {
this.source.subscribe(this);
} else {
this.replay(consumer);
}
}
可以看到,在真正产生订阅的subscribeActual()方法中,首先包装了CacheDisposable:
static final class CacheDisposable<T> extends AtomicInteger implements Disposable {
private static final long serialVersionUID = 6770240836423125754L;
final Observer<? super T> downstream;
final ObservableCache<T> parent;
ObservableCache.Node<T> node;
int offset;
long index;
volatile boolean disposed;
CacheDisposable(Observer<? super T> downstream, ObservableCache<T> parent) {
this.downstream = downstream;
this.parent = parent;
this.node = parent.head;
}
public void dispose() {
if (!this.disposed) {
this.disposed = true;
this.parent.remove(this);
}
}
public boolean isDisposed() {
return this.disposed;
}
}
再来看看remove方法:
//如果Observable是一个无限流,哪怕订阅者自行结束,保留的EMPTY也会引导Observable无限执行下去。
void remove(CacheDisposable<T> consumer) {
for (;;) {
CacheDisposable<T>[] current = observers.get();
int n = current.length;
if (n == 0) {
return;
}
int j = -1;
for (int i = 0; i < n; i++) {
if (current[i] == consumer) {
j = i;
break;
}
}
if (j < 0) {
return;
}
CacheDisposable<T>[] next;
//最后总是保留一个EMPTY
if (n == 1) {
next = EMPTY;
} else {
next = new CacheDisposable[n - 1];
System.arraycopy(current, 0, next, 0, j);
System.arraycopy(current, j + 1, next, j, n - j - 1);
}
if (observers.compareAndSet(current, next)) {
return;
}
}
}
从上篇解读的ObservableSource<T>.subscribe(this)可以知道,内部调用了Observer的onNext()、onError()或者onComplete()方法。对Observer来说,要想主动结束订阅,就在ObservableSource<T>.subscribe(this)处。来看下ObservableCache的下发元素方法:
@Override
public void onNext(T t) {
int tailOffset = this.tailOffset;
// if the current tail node is full, create a fresh node
if (tailOffset == capacityHint) {
Node<T> n = new Node<T>(tailOffset);
n.values[0] = t;
this.tailOffset = 1;
tail.next = n;
tail = n;
} else {
tail.values[tailOffset] = t;
this.tailOffset = tailOffset + 1;
}
size++;
for (CacheDisposable<T> consumer : observers.get()) {
replay(consumer);
}
}
//下面的onError()、onComplete()结束的时候,执行observers.getAndSet(TERMINATED),设置订阅者数组为空,并返回之前数组中的订阅者,通过遍历让订阅者分别结束自己的消费处理流程。
@SuppressWarnings("unchecked")
@Override
public void onError(Throwable t) {
error = t;
done = true;
for (CacheDisposable<T> consumer : observers.getAndSet(TERMINATED)) {
replay(consumer);
}
}
@SuppressWarnings("unchecked")
@Override
public void onComplete() {
done = true;
for (CacheDisposable<T> consumer : observers.getAndSet(TERMINATED)) {
replay(consumer);
}
}
再来看replay(consumer):
if (consumer.disposed) {
consumer.node = null;
return;
}
因为ObservableCache实现了Observer,这里的Observer就是ObservableCache。
不管是Observable还是Observer都应该有能力结束订阅,但Observer解除订阅和Observable解除订阅不应该混为一谈。所以订阅时,使用装饰者设计模式对Observer做了第一次包装为CacheDisposable,这样订阅者便拥有了解除订阅的能力。对于发布订阅的过程,Observable应该主导onNext()、onComplete()、onError(),也就是ObservableCache,并将CacheDisposable纳入其中管理,最后通source.subscribe(this)将两者联系起来,从而做到功能上的解耦。