RxJava2流程分析1- Observable觀察訂閱的的簡單分析

概述:

從最簡單的RxJava的使用,來分析RxJava訂閱和觀察的整個流程(注:RxJava版本:2.2.7)

目標:

  1. RxJava中觀察者和被觀察者是如何聯繫起來的
  2. 被觀察者(Observable)發射數據是從什麼時候開始的,
  3. Observable的整個流程圖

分析

最簡單的RxJava代碼如下:下面代碼實現了 被觀察者,發射一個1,觀察者得到該發射的值並打印出來

Observable.create(new ObservableOnSubscribe<Object>() {
        @Override
        public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onComplete();
        }
    }).subscribe(new Observer<Object>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d("RxJava:", "onSubscribe");
                }

                @Override
                public void onNext(Object o) {
                    Log.d("RxJava:", "onNext"+o.toString());
                }

                @Override
                public void onError(Throwable e) {
                    Log.d("RxJava:", "onError");
                }

                @Override
                public void onComplete() {
                    Log.d("RxJava:", "onComplete");
                }
            });

	運行結果:
	2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onSubscribe
	2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onNext1
	2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onComplete

我們首先查看 Observable.create()方法,如下:

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
	//判斷是否爲空,如果爲null 則拋出異常
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

RxJavaPlugins.onAssembly() 方法

/**
 * Calls the associated hook function. 調用關聯的hook方法
 * @param <T> the value type
 * @param source the hook's input value hook的輸入值
 * @return the value returned by the hook  hook的返回值
 */
 @NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
    Function<? super Observable, ? extends Observable> f = onObservableAssembly;
    if (f != null) {
        return apply(f, source);
    }
    return source;
}
該函數是個hook函數 ,當設置hook函數的時候,會執行hook函數,默認情況下是沒有設置的,即是onObservableAssembly=null,此處我們可以忽略.所以
public static <T> Observable<T> create(ObservableOnSubscribe<T> source)  實際上返回的是new ObservableCreate<T>(source)
整個函數流程即是

new ObservableCreate<T>(source).subscribe(new Observer<Object>() {...}

ObservableCreate類:

//繼承Observable
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;

public ObservableCreate(ObservableOnSubscribe<T> source) {
   //緩存 ObservableOnSubscribe 這個是我們聲明的
   //new ObservableOnSubscribe<Object>() {
   //    @Override
   //     public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
   //         emitter.onNext(1);
   //        emitter.onComplete();
   //    }
   //}
    this.source = source;
}
//實現Observable的抽象函數 這個是重點
@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<T>(observer);
    observer.onSubscribe(parent);

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

我們現在知道了 ObservableCreate是Observable的一個實現類,接下來繼續走流程即是 .subscribe(new Observer<Object>(){}),這個方法點進去是Observable的一個方法,

public abstract class Observable<T> implements ObservableSource<T> {
...
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
	//observer的非空判斷
    ObjectHelper.requireNonNull(observer, "observer is null");
    try {
		//這個是和RxJavaPlugins.onAssembly()一樣的hook方法 默認不走
        observer = RxJavaPlugins.onSubscribe(this, observer);
		//判斷hook後的observer是否非空
        ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
		//實際上調用的方法 
        subscribeActual(observer);
    } catch (NullPointerException e) { // NOPMD
        throw e;
    } catch (Throwable e) {
        Exceptions.throwIfFatal(e);
        // can't call onError because no way to know if a Disposable has been set or not
        // can't call onSubscribe because the call might have set a Subscription already
        RxJavaPlugins.onError(e);

        NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
        npe.initCause(e);
        throw npe;
    }
}
....
//抽象方法
protected abstract void subscribeActual(Observer<? super T> observer);
....
}

我們前面在ObservableCreate類中,看到了其實現的subscribeActual方法

//實現Observable的抽象函數 這個是重點
@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<T>(observer);
	//1
    observer.onSubscribe(parent);
    try {
	//2
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
	//3
        parent.onError(ex);
    }
 }

上述1處:調用observer的onSubscribe方法
 @Override
 public void onSubscribe(Disposable d) {
     Log.d("RxJava:", "onSubscribe");
 }
上述2處:source.subscribe(parent);
在ObservableCreate類中我們看到 source是其保存的ObservableOnSubscribe實例,即是我們在代碼中實現的那個,調用.subscribe(parent)即是:

	 @Override
        public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onComplete();
        }
上述3處 當初source.subscribe的過程中出現異常便會調用 CreateEmitter的onError的方法 最後調用Observer的onNext方法

我們現在知道了  Observable.create(ObservableOnSubscribe).subscribe(Observer) 
實際上是: ObservableOnSubscribe.subscribe(new CreateEmitter(Observer)) ,ObservableOnSubscribe是我們前面實現的 類 ,
我們在其subscribe方法中進行,使用CreateEmitter發射數據 並最終調用complete()方法
接下來我們看下CreateEmitter

CreateEmitter類

    static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {

    private static final long serialVersionUID = -3434801548987643227L;

    final Observer<? super T> observer;

    CreateEmitter(Observer<? super T> observer) {
		//緩存我們設置的觀察者 Observer
        this.observer = observer;
    }
	//該方法是我們在ObservableOnSubscribe的subscribe方法中調用的emitter.onNext(1);
    @Override
    public void onNext(T t) {
		//先判斷髮射在數據是否爲null 
        if (t == null) {
            onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
            return;
        }
		//判斷是否取消了訂閱
        if (!isDisposed()) {
			//執行觀察者Observer的onNext的方法,即是最後我們回調的方法
            observer.onNext(t);
        }
    }
	//在上述3中調用的onError方法 最終調用Observer的onError方法
    @Override
    public void onError(Throwable t) {
        if (!tryOnError(t)) {
			//設置hook方法 忽略
            RxJavaPlugins.onError(t);
        }
    }

    @Override
    public boolean tryOnError(Throwable t) {
		//判空
        if (t == null) {
            t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
        }
		//判斷是否取消了訂閱 取消則不執行
        if (!isDisposed()) {
            try {
				//調用Observer的onError方法
                observer.onError(t);
            } finally {
                dispose();
            }
            return true;
        }
        return false;
    }
	//同上原理 先判斷是否取消訂閱
    @Override
    public void onComplete() {
        if (!isDisposed()) {
            try {
                observer.onComplete();
            } finally {
                dispose();
            }
        }
    }
	//存儲Disposable類 用來判斷是否取消了訂閱
    @Override
    public void setDisposable(Disposable d) {
        DisposableHelper.set(this, d);
    }
	
    @Override
    public void setCancellable(Cancellable c) {
        setDisposable(new CancellableDisposable(c));
    }

    @Override
    public ObservableEmitter<T> serialize() {
        return new SerializedEmitter<T>(this);
    }
	//取消訂閱
    @Override
    public void dispose() {
        DisposableHelper.dispose(this);
    }
	//判斷是否取消了訂閱
    @Override
    public boolean isDisposed() {
        return DisposableHelper.isDisposed(get());
    }

    @Override
    public String toString() {
        return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
    }
}

上述例子的整體流程如下:

  1. 生成ObservableOnSubscribe實例 實現其subscribe(ObservableEmitter emitter)方法,使用emitter發射數據
  2. 生成ObservableCreate實例,該類實現了Observable
  3. Observer訂閱Observable 調用ObservableCreate的subscribeActual(observer)
  4. 生成ObservableEmitter的實例CreateEmitter對象,調用Observer的onSubscribe的方法,
  5. 調用ObservableOnSubscribe的subscribe方法:即是我們上面實現的發射數據的方法

現在回答上面的兩個問題:

  • RxJava中觀察者和被觀察者在ObservableCreate實例中是通過CreateEmitter類關聯起來的
  • 被觀察者(Observable)發射數據是在訂閱後開始發射數據的 即是ObservableOnSubscribe調用subscribe方法
  • Observable的整個流程圖如上面分析

爲了更直觀的分析其整個結構 下面畫出其UML類圖,

ObservableCreate的UML類圖


上面分析以及UML類圖中都指到了Disposable這個接口,該接口主要是實現判斷是否取消訂閱,如果取消訂閱則不再執行想要的回調,我們在CreateEmitter類中也看到了相關的代碼,

	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();
}

在不同的Observable內的實現方式不同,這裏不在詳細說明

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