RxJava原理分析

首先聲明下,本文並不會講解RxJava的基本使用方法,建議對RxJava有一定了解的再來看本文。
RxJava已經有了2.0的版本,而本文是對1.0原理的描述。
RxJava是一個可以實現異步操作的框架,其優點包括可以方便的進行線程轉換,數據轉換以及整個異步實現流程比較清晰,使用鏈式調用。
首先引包

compile 'io.reactivex:rxjava:1.3.0'
compile 'io.reactivex:rxandroid:1.0.1'

調用爲

Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
             subscriber.onNext("Hello");
             subscriber.onNext("Hi");;
             subscriber.onCompleted();
         }
     })
    .map(new Func1<String, Date>() {
        @Override
        public Date call(String s) {
             return null;
        }
    })
   .observeOn(AndroidSchedulers.mainThread())
   .subscribeOn(Schedulers.io())
   .subscribe(new Action1<Date>() {
        @Override
        public void call(Date date) {

        }
   });

其中create用於規定觸發規則,map用於進行數據轉換,subscribeOn決定了訂閱的線程,observeOn決定了事件處理的線程,subscribe則是最後的事件處理。接下來從源碼上看看他到底是怎麼做到的。
首先,最簡單的

Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
             subscriber.onNext("Hello");
             subscriber.onNext("Hi");;
             subscriber.onCompleted();
         }
     })
   .subscribe(new Action1<Date>() {
        @Override
        public void call(Date date) {

        }
   });

不添加參數變化功能,不管線程的轉換,那麼他做了什麼,首先看create方法

public static <T> Observable<T> create(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }

protected Observable(OnSubscribe<T> f) {
        this.onSubscribe = f;
    }

沒什麼特別的,就是創建一個Observable對象和一個與Observable相對應的OnSubscribe對象
接下來subscribe的實現

public final Subscription subscribe(final Action1<? super T> onNext) {
        ......
        return subscribe(new ActionSubscriber<T>(onNext, onError, onCompleted));
    }

有很多重載的方法,我選了最簡單的一個,最後都會調到subscribe(Subscriber subscriber)

public final Subscription subscribe(Subscriber<? super T> subscriber) {
        return Observable.subscribe(subscriber, this);
    }

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
        ......
        subscriber.onStart();
        ......
        RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
        return RxJavaHooks.onObservableReturn(subscriber);        
        }
    }

就是先調用subscriber的onStart方法,接着調用OnSubscribe的call方法,結合上下文,其實也就是調用subscriber的onNext和onCompleted等方法。邏輯上很好理解,那麼接下來我們增加了map方法,變成了

Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
             subscriber.onNext("Hello");
             subscriber.onNext("Hi");;
             subscriber.onCompleted();
         }
     })
    .map(new Func1<String, Date>() {
        @Override
        public Date call(String s) {
             return null;
        }
    })
   .subscribe(new Action1<Date>() {
        @Override
        public void call(Date date) {

        }
   });

看看map方法做了什麼

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
        return unsafeCreate(new OnSubscribeMap<T, R>(this, func));
    }

public static <T> Observable<T> unsafeCreate(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }

他又創建了一個Observable對象,所以我們可以從這裏知道,Observable的鏈式調用並不是用對象本身不停地鏈啊鏈,實際上,經過每一次變換,包括線程啊,參數啊,他都會新建一個Observable對象並返回新建的對象。
我們回來接着看這個Observable對象,很明顯,關鍵在於OnSubscribeMap這個類

public final class OnSubscribeMap<T, R> implements OnSubscribe<R> {
    final Observable<T> source;
    final Func1<? super T, ? extends R> transformer;
    public OnSubscribeMap(Observable<T> source, Func1<? super T, ? extends R> transformer) {
        this.source = source;
        this.transformer = transformer;
    }
    @Override
    public void call(final Subscriber<? super R> o) {
        MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
        o.add(parent);
        source.unsafeSubscribe(parent);
    }
}

可以看到這個OnSubscribeMap繼承了OnSubscribe,其會持有上一層的Observable對象source以及我們實現了轉換方法的對象transformer。
關鍵在於其默認的call方法,首先提醒下他的參數final Subscriber o是下一層調用subscribe時傳進的subscriber對象。
我們看MapSubscriber對象

static final class MapSubscriber<T, R> extends Subscriber<T> {
        final Subscriber<? super R> actual;
        final Func1<? super T, ? extends R> mapper;
        boolean done;
        public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
            this.actual = actual;
            this.mapper = mapper;
        }
        @Override
        public void onNext(T t) {
            R result = mapper.call(t);
            actual.onNext(result);
        }
    }

他是個Subscriber,是個觀察者。就拿我們寫的map(new Func1<>String, Date>())來說,也就是上面的T都是String,而R則是Date,在調用他的onNext方法時,首先調用轉換參數方法,將String轉換爲Date,之後將轉換的Date給到下一層的Subscriber來進行處理。
再看source.unsafeSubscribe(parent),記得吧,source是上一層的Observable對象

public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
        ......
        subscriber.onStart();
        RxJavaHooks.onObservableStart(this, onSubscribe).call(subscriber);
        return RxJavaHooks.onObservableReturn(subscriber);
        }
    }

所以如果這一層的Observable是發送消息時創建的,那麼他就會調用subscriber的onNext等方法,而如果他是由map創建的,則就繼續封裝變換方法,創建新的subscriber對象,繼續將新創建的subscriber對象扔給上一層Observable處理,以此類推
這裏寫圖片描述
接着我們看看實現了線程轉換的subscribeOn和observeOn都做了什麼
先來subscribeOn

public final Observable<T> subscribeOn(Scheduler scheduler) {
        return subscribeOn(scheduler, !(this.onSubscribe instanceof OnSubscribeCreate));
    }

public final Observable<T> subscribeOn(Scheduler scheduler, boolean requestOn) {
        if (this instanceof ScalarSynchronousObservable) {
            return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
        }
        return unsafeCreate(new OperatorSubscribeOn<T>(this, scheduler, requestOn));
    }

public static <T> Observable<T> unsafeCreate(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }

又是一個Observable,關鍵還是在於他的OnSubscribe,也就是OperatorSubscribeOn

public final class OperatorSubscribeOn<T> implements OnSubscribe<T> {

    final Scheduler scheduler;
    final Observable<T> source;
    final boolean requestOn;

    public OperatorSubscribeOn(Observable<T> source, Scheduler scheduler, boolean requestOn) {
        this.scheduler = scheduler;
        this.source = source;
        this.requestOn = requestOn;
    }

    @Override
    public void call(final Subscriber<? super T> subscriber) {
        final Worker inner = scheduler.createWorker();

        SubscribeOnSubscriber<T> parent = new SubscribeOnSubscriber<T>(subscriber, requestOn, inner, source);
        subscriber.add(parent);
        subscriber.add(inner);

        inner.schedule(parent);
    }
}

可以看到整體思路還是一樣的,繼續往上拋,不過inner.schedule(parent)說明他並不是在原始的線程裏拋,根據你傳遞的Scheduler以此決定在哪個線程裏拋,然後之後的流程也隨之切換到了新線程,現在我們可以回答兩個問題了
第一個:爲什麼subscribeOn只有一個起作用,而且是第一個。因爲我們所寫的那些轉換等方法其實最後都是實現在了subscriber的onNext的方法中,多個subscribeOn方法其實實現了線程切換,不過實現在往上拋的過程,並沒有在我們的代碼中體現出來,第一個subscribeOn是最後調用的,是我們能看的到的
第二個:Observable有一個doOnSubscribe方法,調用他時的線程由他之後的第一個subscribeOn方法決定。這是因爲他的實現是在拋的那一條線執行的。

public final Observable<T> doOnSubscribe(final Action0 subscribe) {
        return lift(new OperatorDoOnSubscribe<T>(subscribe));
    }

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return unsafeCreate(new OnSubscribeLift<T, R>(onSubscribe, operator));
    }

public class OperatorDoOnSubscribe<T> implements Operator<T, T> {
    private final Action0 subscribe;
    public OperatorDoOnSubscribe(Action0 subscribe) {
        this.subscribe = subscribe;
    }
    @Override
    public Subscriber<? super T> call(final Subscriber<? super T> child) {
        subscribe.call();
        return Subscribers.wrap(child);
    }
}

subscribeOn處理的是拋的那一條線,也就是OnSubscribe的call那一線,那麼很明顯了observeOn處理的就是另一條線,Subscriber的onNext方法了,看看源碼

public final Observable<T> observeOn(Scheduler scheduler) {
        return observeOn(scheduler, RxRingBuffer.SIZE);
    }

public final Observable<T> observeOn(Scheduler scheduler, int bufferSize) {
        return observeOn(scheduler, false, bufferSize);
    }

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        if (this instanceof ScalarSynchronousObservable) {
            return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
        }
        return lift(new OperatorObserveOn<T>(scheduler, delayError, bufferSize));
    }

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return unsafeCreate(new OnSubscribeLift<T, R>(onSubscribe, operator));
    }

public static <T> Observable<T> unsafeCreate(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }

按照經驗,找OnSubscribe,也就是OnSubscribeLift

public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {

    final OnSubscribe<T> parent;

    final Operator<? extends R, ? super T> operator;

    public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
        this.parent = parent;
        this.operator = operator;
    }

    @Override
    public void call(Subscriber<? super R> o) {
        Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);        
        st.onStart();
        parent.call(st);        
    }
}

可以看到call方法沒有什麼特別,我們看看Subscriber,它是由operator的call方法生成的,operator是OperatorObserveOn類

public final class OperatorObserveOn<T> implements Operator<T, T> {

    private final Scheduler scheduler;
    private final boolean delayError;
    private final int bufferSize;

    public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
    }

    @Override
    public Subscriber<? super T> call(Subscriber<? super T> child) {
         ObserveOnSubscriber<T> parent = new ObserveOnSubscriber<T>(scheduler, child, delayError, bufferSize);
         parent.init();
         return parent;
    }
}

這個Subscriber是ObserveOnSubscriber,是OperatorObserveOn的一個內部類

static final class ObserveOnSubscriber<T> extends Subscriber<T> implements Action0 {
        final Subscriber<? super T> child;
        final Scheduler.Worker recursiveScheduler;
        final boolean delayError;

        public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> child, boolean delayError, int bufferSize) {
            this.child = child;
            this.recursiveScheduler = scheduler.createWorker();
            this.delayError = delayError;

        @Override
        public void onNext(final T t) {
            ......
            schedule();
        }

        protected void schedule() {
            if (counter.getAndIncrement() == 0) {
                recursiveScheduler.schedule(this);
            }
        }
    }

可以看到在onNext最後進行了線程轉換,所以observeOn可以多次改變運行線程

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