RxAndroid dispose實現原理

示例如下:

    final Disposable disposable = Observable.create(new ObservableOnSubscribe<String>() {
        public void subscribe(@NonNull ObservableEmitter<String> e) {
            for (int i=0; i<100; i++) {
                if (e.isDisposed())
                    break;
                Thread.sleep(1000);
                e.onNext(String.valueOf(i));
            }
            e.onComplete();
        }
    }).map(new Function<Integer, String>() {
          public String apply(Integer number) {
            return number.toString();
          }
    }).subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe();
    new Handler().postDelayed(new Runnable() {
        public void run() {
            disposable.dispose();
        }
    }, 3000);

問題:

爲什麼調用disposable.dispose之後,ObservableEmitter.isDisposed爲true?

分析:

經過調試發現,disposable.dispose這一句執行後最終會調用ObservableCreate.CreateEmitter.dispose。

【connect】在observer.onSubscribe時連接成一條線

  1. Disposable是什麼?
  2. 怎樣連接起來?
  3. 怎樣跨越線程?
  4. 怎樣跨越操作符?

1,Disposable是一個interface

/**
 * Represents a disposable resource.
 */
public interface Disposable {
    /**
     * Dispose the resource, the operation should be idempotent.
     */
    void dispose();

    /**
     * Returns true if this resource has been disposed.
     * @return true if this resource has been disposed
     */
    boolean isDisposed();
}

2,當subscribe調用後,會構造一個LambdaObserver,最終返回的Dispose就是這個。

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
        Action onComplete, Consumer<? super Disposable> onSubscribe) {
    ObjectHelper.requireNonNull(onNext, "onNext is null");
    ObjectHelper.requireNonNull(onError, "onError is null");
    ObjectHelper.requireNonNull(onComplete, "onComplete is null");
    ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");

    LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);

    subscribe(ls);

    return ls;
}

假設只有Observable.create與subscribe,那麼,將會進入ObservableCreate.subscribeActual

@Override
protected void subscribeActual(Observer<? super T> observer) {
    // observer即傳入的LambdaObserver
    CreateEmitter<T> parent = new CreateEmitter<T>(observer);
    // 重點在此,看看裏面做了什麼
    observer.onSubscribe(parent);

    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}

LambdaObserver.onSubscribe

@Override
public void onSubscribe(Disposable d) {
    // 注意,繼承了AtomicReference<Disposable>的類內部都有一個
    // volatile Disposable value,
    // 此處就是保存傳入的Disposable(CreateEmitter),如此,
    // 當LambdaObserver的dispose調用時,會調用到CreateEmitter.dispose
    if (DisposableHelper.setOnce(this, d)) {
        try {
            onSubscribe.accept(this);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            d.dispose();
            onError(ex);
        }
    }
}

3,先看subscribeOn,ObservableSubscribeOn

@Override
public void subscribeActual(final Observer<? super T> observer) {
    final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
    // downstream保存SubscribeOnObserver對象(Disposable)
    observer.onSubscribe(parent);
    // 任務拋到線程,並且將其Disposable對象保存
    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}

當source.subscribe調用後,SubscribeOnObserver內onSubscribe如下

@Override
public void onSubscribe(Disposable d) {
    // 將上游observable保存到upstream中
    DisposableHelper.setOnce(this.upstream, d);
}

當LambdaObserver.dispose調用後,SubscribeOnObserver內dispose被調用

@Override
public void dispose() {
    // 觸發上游dispose
    DisposableHelper.dispose(upstream);
    // dispose任務,任務在線程中執行會先判斷isDisposed再決定是否執行
    DisposableHelper.dispose(this);
}

再看observeOn,ObservableObserveOn

@Override
protected void subscribeActual(Observer<? super T> observer) {
    if (scheduler instanceof TrampolineScheduler) {
        source.subscribe(observer);
    } else {
        Scheduler.Worker w = scheduler.createWorker();
        // ObserveOnObserver.onNext時,會在worker中執行observer.onNext
        source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
    }
}

ObservableObserveOn.onSubscribe

@Override
public void onSubscribe(Disposable d) {
    if (DisposableHelper.validate(this.upstream, d)) {
        // 將CreateEmitter保存起來
        this.upstream = d;
        if (d instanceof QueueDisposable) {
            @SuppressWarnings("unchecked")
            QueueDisposable<T> qd = (QueueDisposable<T>) d;

            int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);

            if (m == QueueDisposable.SYNC) {
                sourceMode = m;
                queue = qd;
                done = true;
                downstream.onSubscribe(this);
                schedule();
                return;
            }
            if (m == QueueDisposable.ASYNC) {
                sourceMode = m;
                queue = qd;
                downstream.onSubscribe(this);
                return;
            }
        }

        queue = new SpscLinkedArrayQueue<T>(bufferSize);
        // downstream保存此Disposable對象
        downstream.onSubscribe(this);
    }
}

LambdaObserver.dispose調用後,會執行ObservableObserveOn.dispose

@Override
public void dispose() {
    if (!disposed) {
        disposed = true;
        // 中止上游任務
        upstream.dispose();
        // 中止線程中的任務
        worker.dispose();
        if (getAndIncrement() == 0) {
            queue.clear();
        }
    }
}

 

4,以map爲例

Observable.create().map().subscribe();

內部保存upstream,並把自己保存在downstream的Disposable對象中。

從map.subscribeActual開始

@Override
public void subscribeActual(Observer<? super U> t) {
    // source爲ObservableCreate
    // t爲LambdaObserver
    source.subscribe(new MapObserver<T, U>(t, function));
}

source.subscribe調用後會進入MapObserver.onSubscribe,在基類中BasicFuseableObserver

@Override
public final void onSubscribe(Disposable d) {
    // d爲CreateEmitter,保存爲upstream
    if (DisposableHelper.validate(this.upstream, d)) {
        this.upstream = d;
        if (d instanceof QueueDisposable) {
            this.qd = (QueueDisposable<T>)d;
        }
        if (beforeDownstream()) {
            // downstream爲LambdaObserver,在構造函數中賦值的
            // 該句調用後,LambdaObserver保存此對象Disposable
            downstream.onSubscribe(this);

            afterDownstream();
        }
    }
}

因此,LambdaObserver.dispose調用後,會調用MapObserver.dispose

@Override
public void dispose() {
    // upstream即上面的CreateEmitter
    upstream.dispose();
}

總結:

下游會保存上游的Disposable對象,從而,在下游開始調用dispose後,實際上是去調用上游的dispose,如此,直到第一個Observable對象調用dispose停止,從而達到每個Disposable對象都爲DISPOSED。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章