RxJava2.0中just操作符用法和源碼分析(二)

just基本使用

just是用來創建一個Observable來發射指定值,可以將任何對象轉化爲一個用來被髮射的ObservableSource數據。這個方法與fromArray相似,除了from會將數組或者Iterable中的元素逐個取出然後在逐個依次發射,而just會直接將數組或者Iterable對象作爲單個數據來發射。
image

實例代碼:

Integer[] items = { 0, 1, 2, 3, 4, 5 };
Observable.just(items).subscribe(new Consumer<Integer[]>() {
    @Override
    public void accept(Integer[] integers) throws Exception {
        for (int i : integers) {
            println("accept : onNext : " + i + "\n");
        }
    }
});

just接收一個用於發射的數據,我們查看源碼發現just有許多重載的方法:

just(T item)

just(T item1, T item2)

just(T item1, T item2, T item3)

just(T item1, T item2, T item3, T item4)

just(T item1, T item2, T item3, T item4, T item5)

just(T item1, T item2, T item3, T item4, T item5, T item6)

just(T item1, T item2, T item3, T item4, T item5, T item6, T item7)

just(T item1, T item2, T item3, T item4, T item5, T item6, T item7, T item8)

just(T item1, T item2, T item3, T item4, T item5, T item6, T item7, T item8, T item9)

just(T item1, T item2, T item3, T item4, T item5, T item6, T item7, T item8, T item9, T item10)

上面不同的重載方法分別用來接收不同數量的item,然後分別發射這些item。我們在看just方法中的實現:

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> just(T item) {
    ObjectHelper.requireNonNull(item, "The item is null");
    return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}

public static <T> Observable<T> just(T item1, T item2) {
    ObjectHelper.requireNonNull(item1, "The first item is null");
    ObjectHelper.requireNonNull(item2, "The second item is null");

    return fromArray(item1, item2);
}

public static <T> Observable<T> fromArray(T... items) {
    ObjectHelper.requireNonNull(items, "items is null");
    if (items.length == 0) {
        return empty();
    } else
    if (items.length == 1) {
        return just(items[0]);
    }
    return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));
}

當just中接收的是一個item時,直接調用RxJavaPlugins.onAssembly(new ObservableJust(item)),如果是多個item,那麼會先去判斷item的合法性,然後再去調用RxJavaPlugins.onAssembly(new ObservableFromArray(items)).我們來逐個分析,先看單個item的調用:

Observable#just(T item)

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> just(T item) {
    ObjectHelper.requireNonNull(item, "The item is null");
    return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}

首先通過參數item,生成一個ObservableJust的對象,該類比較簡單如下:

ObservableJust

/**
 * Represents a constant scalar value.
 * @param <T> the value type
 */
public final class ObservableJust<T> extends Observable<T> implements ScalarCallable<T> {

    private final T value;
    public ObservableJust(final T value) {
        this.value = value;
    }

    @Override
    protected void subscribeActual(Observer<? super T> s) {
        ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
        s.onSubscribe(sd);
        sd.run();
    }

    @Override
    public T call() {
        return value;
    }
}

將上面生成的ObservableJust類對象,作爲onAssembly方法參數,進行裝配:

RxJavaPlugins#onAssembly

@SuppressWarnings({ "rawtypes", "unchecked" })
@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;
}

到這裏,我們知道會返回該Observable對象,而這個對象具體實現類就是ObservableJust對象。
完成了Observable初始化後,我們開始訂閱以個觀察者對象。在這裏我選擇了Consumer對象。我們來看看這個類:

public interface Consumer<T> {
    /**
     * Consume the given value.
     * @param t the value
     * @throws Exception on error
     */
    void accept(@NonNull T t) throws Exception;
}

這個類十分簡單,是標準的函數式接口,裏面只有以個accept方法。現在我們重點來看看Observable中的subscribe方法。這裏面同樣對該方法進行了重載:

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext) {
    return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION, Functions.emptyConsumer());
}

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {
    return subscribe(onNext, onError, Functions.EMPTY_ACTION, Functions.emptyConsumer());
}

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
        Action onComplete) {
    return subscribe(onNext, onError, onComplete, Functions.emptyConsumer());
}

@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;
}

當你使用Consumer作爲參數時,最多可以接收4個參數:
Consumer

@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
    ObjectHelper.requireNonNull(observer, "observer is null");
    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);

        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

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

這裏主要是執行了subscribeActual方法,而這個方法在Observable中是個抽象的方法,前面我們已經知道Observable的具體實現類是ObservableJust類,所以具體執行的也是這個類中的方法:

ObservableJust#subscribeActual

@Override
protected void subscribeActual(Observer<? super T> s) {
    ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
    s.onSubscribe(sd);
    sd.run();
}

方法裏面首先創建了一個ScalarDisposable對象,然後將它作爲參數執行傳入的Observer的onSubscribe方法。
而我們又知道Observer對象就是剛纔創建的LambdaObserver對象。

LambdaObserver#onSubscribe

public final class LambdaObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {

    ......

    public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
            Action onComplete,
            Consumer<? super Disposable> onSubscribe) {
        super();
        this.onNext = onNext;
        this.onError = onError;
        this.onComplete = onComplete;
        this.onSubscribe = onSubscribe;
    }

    @Override
    public void onSubscribe(Disposable s) {
        if (DisposableHelper.setOnce(this, s)) {
            try {
                onSubscribe.accept(this);
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                s.dispose();
                onError(ex);
            }
        }
    }

    ......
}

從這裏可以知道onSubscribe方法中,其實是調用的onSubscribe實例中的accept方法。而這個onSubscribe又是在LambdaObserver實例化時,傳入的第四個參數。這裏將ObservableJust中subscribeActual方法裏面的創建的ScalarDisposable對象,通過該方法回調傳出來,用來觀察ObservableJust的狀態是否被斷開。
接下來將會執行ScalarDisposable中的run方法:

public static final class ScalarDisposable<T> extends AtomicInteger implements QueueDisposable<T>, Runnable {

    private static final long serialVersionUID = 3880992722410194083L;

    final Observer<? super T> observer;

    final T value;

    static final int START = 0;
    static final int FUSED = 1;
    static final int ON_NEXT = 2;
    static final int ON_COMPLETE = 3;

    public ScalarDisposable(Observer<? super T> observer, T value) {
        this.observer = observer;
        this.value = value;
    }

    .....

    @Override
    public void run() {
        if (get() == START && compareAndSet(START, ON_NEXT)) {
            observer.onNext(value);
            if (get() == ON_NEXT) {
                lazySet(ON_COMPLETE);
                observer.onComplete();
            }
        }
    }
}

上面的分析我們知道這個observer其實就是LambdaObserver的實例化對象。通過它來執行LambdaObserver中的onNext方法,當完成發送時再去執行observer.onComplete()

LambdaObserver#onNext

@Override
public void onNext(T t) {
    if (!isDisposed()) {
        try {
            onNext.accept(t);
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            get().dispose();
            onError(e);
        }
    }
}

@Override
public void onError(Throwable t) {
    if (!isDisposed()) {
        lazySet(DisposableHelper.DISPOSED);
        try {
            onError.accept(t);
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            RxJavaPlugins.onError(new CompositeException(t, e));
        }
    }
}

@Override
public void onComplete() {
    if (!isDisposed()) {
        lazySet(DisposableHelper.DISPOSED);
        try {
            onComplete.run();
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            RxJavaPlugins.onError(e);
        }
    }
}

而這裏的onNext對象就是傳入的第一個參數Consumer對象。於是第一個參數的Consumer的回調參數得到了執行。如果出現異常則會調用onError方法,該方法裏面通過onError(第二個參數)的回調方法accept將錯誤信息傳遞出來。當執行完畢後就會調用onComplete方法,然後通過onComplete(第三個參數Action)回調run方法。到這裏就完成了對just操作符的分析。

下面列出just的簡單demo:

Observable.just(1,2,3).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        println("accept : onNext : " + integer + "\n");
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        println("accept : throwable : " + throwable.getMessage() + "\n");
    }
}, new Action() {
    @Override
    public void run() throws Exception {
        println("accept : run" + "\n");
    }
}, new Consumer<Disposable>() {
    @Override
    public void accept(Disposable disposable) throws Exception {
        println("accept : disposable : " + disposable.isDisposed() + "\n");
    }
});


執行結果:

accept : disposable : false

accept : onNext : 1

accept : onNext : 2

accept : onNext : 3

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