RxJava 源碼分析(一)

RxJava 現在用的比較廣泛了,尤其是用在網絡中,我們來看看它到底是什麼,怎麼用。這裏以 1.1 版本爲例,比較早起的本,使用的時候,先註明引用

implementation 'io.reactivex:rxjava:1.1.7'

我們先來看個簡單的例子,這是在Java中寫的, 

  private static void initRxJava1(){

        Observable
                .create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        System.out.println(" create    "  +  Thread.currentThread().getName() );
                        // 重點一
                        subscriber.onNext("hi");
                        subscriber.onCompleted();
                    }
                })
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        System.out.println(  "  onCompleted  " );
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        int num = Runtime.getRuntime().availableProcessors();
                        System.out.println(s + "   " + num + "     "  +  Thread.currentThread().getName());
                    }
                });
    }

這個例子中,打印的值爲

 create    main
hi   4     main
  onCompleted

我們知道,RxJava 是響應鏈式編程,顧名思義就是從上往下相應的編程,上面知識一個最簡單的例子,我們來分析一下代碼,看看它是怎麼從上往下執行的


Observable: 

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

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

RxJavaHooks:

 public static <T> Observable.OnSubscribe<T> onCreate(Observable.OnSubscribe<T> onSubscribe) {
        Func1<OnSubscribe, OnSubscribe> f = onObservableCreate;
        if (f != null) {
            return f.call(onSubscribe);
        }
        return onSubscribe;
    }

在這裏,我們可以簡化點,認爲 RxJavaHooks.onCreate(f) 中返回的就是 f 值本身,這樣,通過第一步 Observable.create() 方法就創建一個 Observable 對象,暫時記爲 Ob1,它裏面的 onSubscribe 屬性紀委 onS1;繼續往下看,此時調用了 subscribe() 方法,傳入了 Subscriber 對象, Subscriber 是個抽象類,它實現了 Observer 和 Subscription 接口,其實這裏傳入一個 Observer 對象也是可以的,它會被包裝一層,轉化爲 ObserverSubscriber 對象繼續調用 subscribe(Subscriber<? super T> subscriber)方法,ObserverSubscriber 是 Subscriber 的子類,是個裝飾模式。繼續看 subscribe() 方法,稱傳入的 Subscriber 對象爲 Sub1, 

   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();
        
        if (!(subscriber instanceof SafeSubscriber)) {
            subscriber = new SafeSubscriber<T>(subscriber);
        }
        try {
            RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
            return RxJavaHooks.onObservableReturn(subscriber);
        } catch (Throwable e) {
            ...
            return Subscriptions.unsubscribed();
        }
    }

這是簡化後的代碼,其實 try...catch 中可以簡化一行代碼 observable.onSubscribe.call(subscriber); 也就是說可以是

 

   static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
        
        subscriber.onStart();
        
        if (!(subscriber instanceof SafeSubscriber)) {
            subscriber = new SafeSubscriber<T>(subscriber);
        }
        try {
            observable.onSubscribe.call(subscriber);
            return subscriber;
        } catch (Throwable e) {
            ...
            return Subscriptions.unsubscribed();
        }
    }

此時,在 Ob1 中,subscriber 對象傳進來時是 Sub1,先執行它的 onStart() 方法;然後包裹一層,轉爲爲 SafeSubscriber 對象,此時記做 SafeSub1, observable.onSubscribe 對應的是 onS1,也就是說它調用了 call() 方法,裏面傳入的對象是 SafeSubscriber 類型的 SafeSub1,看看它的代碼


public class SafeSubscriber<T> extends Subscriber<T> {

    private final Subscriber<? super T> actual;

    boolean done;

    public SafeSubscriber(Subscriber<? super T> actual) {
        super(actual);
        this.actual = actual;
    }

    @Override
    public void onCompleted() {
        try {
            actual.onCompleted();
        } catch (Throwable e) {
            throw new OnCompletedFailedException(e.getMessage(), e);
        }
    }

    @Override
    public void onNext(T args) {
        try {
            if (!done) {
                actual.onNext(args);
            }
        } catch (Throwable e) {
            Exceptions.throwOrReport(e, this);
        }
    }
}

這是簡化後的代碼,說是安全,其實就是添加了個boolean屬性,防止重複執行,例如 onNext() 方法中就是保留的例子。SafeSubscriber 是 Subscriber 的子類,看它構造方法中調用了 super(actual) 方法,把傳進來的 Sub1 傳給了父類,這裏可以先不用看它的父類,對邏輯沒影響。繼續回到 observable.onSubscribe.call(subscriber) 這行代碼,此時執行了 initRxJava1() 中的 new Observable.OnSubscribe<String>() 對象中的 call() 回調,打印了 create    main 字符串,然後執行了 重點一 的代碼,如果沒有在這兩行代碼,整個流程到此結束,我們看看,此時 subscriber 就是 SafeSubscriber 類型,即 SafeSub1 , 執行的 onNext() 和 onCompleted() 都是它內部屬性也就是 Sub1 對應的方法,Sub1 就是 initRxJava1() 方法中的 new Subscriber<String>() 對象,此時執行它裏面的打印方法,這個調用流程就是這樣。


看看方法 initRxJava2(),會有個不一樣的體驗效果 

  private static void initRxJava2(){

        Observable
                .just("hello")
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        System.out.println(  "  onCompleted  " );
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        int num = Runtime.getRuntime().availableProcessors();
                        System.out.println(s + "   " + num + "     "  +  Thread.currentThread().getName());
                    }
                });
    }

打印的值爲

hello   4     main
  onCompleted

這個明顯沒有地方調用 onNext() 和 onCompleted() 方法,爲什麼會調用呢?看看它裏面的代碼

    public static <T> Observable<T> just(final T value) {
        return ScalarSynchronousObservable.create(value);
    }

ScalarSynchronousObservable: 

   public static <T> ScalarSynchronousObservable<T> create(T t) {
        return new ScalarSynchronousObservable<T>(t);
    }

    protected ScalarSynchronousObservable(final T t) {
        super(RxJavaHooks.onCreate(new JustOnSubscribe<T>(t)));
        this.t = t;
    }

    static final class JustOnSubscribe<T> implements OnSubscribe<T> {
        final T value;

        JustOnSubscribe(T value) {
            this.value = value;
        }

        @Override
        public void call(Subscriber<? super T> s) {
            s.setProducer(createProducer(s, value));
        }
    }

這裏是生成了一個 ScalarSynchronousObservable 對象,它是 Observable 的子類,ScalarSynchronousObservable 的構造方法中可以忽略 RxJavaHooks 的方法代碼,直接理解爲 super(new JustOnSubscribe<T>(t)) 即可,這裏是創建了一個 JustOnSubscribe 對象傳給了父類,即 onSubscribe 屬性爲 JustOnSubscribe 對象。繼續看 initRxJava2() 中方法,這裏也執行到了 subscribe() 方法,老樣子,先把 Subscriber 對象包裹一層,轉換爲 SafeSubscriber 對象,然後執行 JustOnSubscribe 的 call() 方法,方法中的形參就是 SafeSubscriber 類型,先看看 createProducer(s, value) 方法

    static <T> Producer createProducer(Subscriber<? super T> s, T v) {
        if (STRONG_MODE) {
            return new SingleProducer<T>(s, v);
        }
        return new WeakSingleProducer<T>(s, v);
    }

這裏創建的是 WeakSingleProducer 對象

    static final class WeakSingleProducer<T> implements Producer {
        final Subscriber<? super T> actual;
        final T value;
        boolean once;
        
        public WeakSingleProducer(Subscriber<? super T> actual, T value) {
            this.actual = actual;
            this.value = value;
        }
        
        ...
    }

s.setProducer(createProducer(s, value)) 中的 s 是 SafeSubscriber 類型,它是 Subscriber 的子類,調用了 setProducer() 方法,看看它的代碼

public abstract class Subscriber<T> implements Observer<T>, Subscription {

    private static final long NOT_SET = Long.MIN_VALUE;

    private final SubscriptionList subscriptions;
    private final rx.Subscriber<?> subscriber;
    private Producer producer;
    private long requested = NOT_SET; // default to not set

    protected Subscriber() {
        this(null, false);
    }

    protected Subscriber(rx.Subscriber<?> subscriber) {
        this(subscriber, true);
    }

    protected Subscriber(rx.Subscriber<?> subscriber, boolean shareSubscriptions) {
        this.subscriber = subscriber;
        this.subscriptions = shareSubscriptions && subscriber != null ? subscriber.subscriptions : new SubscriptionList();
    }

    public void onStart() {
        // do nothing by default
    }

    public void setProducer(Producer p) {
        long toRequest;
        boolean passToSubscriber = false;
        synchronized (this) {
            toRequest = requested;
            producer = p;
            if (subscriber != null) {
                // middle operator ... we pass through unless a request has been made
                if (toRequest == NOT_SET) {
                    // we pass through to the next producer as nothing has been requested
                    passToSubscriber = true;
                }
            }
        }
        // do after releasing lock
        if (passToSubscriber) {
            subscriber.setProducer(producer);
        } else {
            // we execute the request with whatever has been requested (or Long.MAX_VALUE)
            if (toRequest == NOT_SET) {
                producer.request(Long.MAX_VALUE);
            } else {
                producer.request(toRequest);
            }
        }
    }
}

裏面比較重要的是構造方法和 setProducer() 這個方法,由於調用的一個參數的構造方法,所以 subscriber 和 subscriptions 都有值,此時 setProducer()中,形參 Producer 是 WeakSingleProducer 類型, s 是 SafeSubscriber 類型,setProducer() 中  synchronized 代碼塊中,會執行到 passToSubscriber = true這一步,然後就是 subscriber.setProducer(producer) 這行代碼,此時 subscriber 就是 initRxJava2() 中的 new Subscriber<String>() 對象,producer 是 WeakSingleProducer,執行後,還是會執行
setProducer(Producer p) 方法,區別是此時方法所屬的對象是 Subscriber 而非 SafeSubscriber,我們繼續看,由於此時 subscriber 爲null,所以 passToSubscriber 值是false,執行 else 中的操作  producer.request(Long.MAX_VALUE) 代碼,因此回到了 WeakSingleProducer 中

    static final class WeakSingleProducer<T> implements Producer {
        final Subscriber<? super T> actual;
        final T value;
        boolean once;
        
        public WeakSingleProducer(Subscriber<? super T> actual, T value) {
            this.actual = actual;
            this.value = value;
        }
        
        @Override
        public void request(long n) {
            Subscriber<? super T> a = actual;
            T v = value;
            try {
                a.onNext(v);
            } catch (Throwable e) {
                return;
            }
            a.onCompleted();
        }
    }

簡化後代碼,此時 actual 就是 SafeSubscriber ,因此調用還是它內部的 onNext() 、onCompleted() 方法,它內部執行 initRxJava2() 中 new Subscriber<String>() 對象的方法。故此,我們沒有明文像 initRxJava1() 中的 重點一 代碼,卻也執行了打印方法。

   private static void initRxJava3(){

        Observable
                .just("hello","world")
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        System.out.println(  "  onCompleted  " );
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        int num = Runtime.getRuntime().availableProcessors();
                        System.out.println(s + "   " + num + "     "  +  Thread.currentThread().getName());
                    }
                });
    }

注意,just() 方法中傳入的是兩個字符串,看看運行的結果

hello   4     main
world   4     main
  onCompleted  
  


onNext() 方法執行了兩次,這是爲什麼呢?老規矩,看源碼
 

   public static <T> Observable<T> just(T t1, T t2) {
        return from((T[])new Object[] { t1, t2 });
    }

    public static <T> Observable<T> empty() {
        return EmptyObservableHolder.instance();
    }
    
    public static <T> Observable<T> from(T[] array) {
        int n = array.length;
        if (n == 0) {
            return empty();
        } else
        if (n == 1) {
            return just(array[0]);
        }
        return create(new OnSubscribeFromArray<T>(array));
    }

由此可以看出,如果數組長度爲0,返回的是 EmptyObservableHolder 中的單利對象,它只會執行 Subscriber 的 onCompleted() 方法;數組長度爲1時,還是調用 just() 方法;數組長度超過1時,這裏又創建了 OnSubscribeFromArray 對象。

public final class OnSubscribeFromArray<T> implements Observable.OnSubscribe<T> {
    final T[] array;
    public OnSubscribeFromArray(T[] array) {
        this.array = array;
    }

    @Override
    public void call(Subscriber<? super T> child) {
        child.setProducer(new FromArrayProducer<T>(child, array));
    }

    static final class FromArrayProducer<T>
            extends AtomicLong
            implements Producer {

        final Subscriber<? super T> child;
        final T[] array;

        public FromArrayProducer(Subscriber<? super T> child, T[] array) {
            this.child = child;
            this.array = array;
        }

        @Override
        public void request(long n) {
            ...
            fastPath();
            ...
        }

        void fastPath() {
            final Subscriber<? super T> child = this.child;
            for (T t : array) {
                if (child.isUnsubscribed()) {
                    return;
                }
                child.onNext(t);
            }
            if (child.isUnsubscribed()) {
                return;
            }
            child.onCompleted();
        }

    }
}

這個是簡化後的代碼,看過 initRxJava2() 方法中的代碼分析,知道 OnSubscribeFromArray 中的 call() 方法中的參數 child 是 SafeSubscriber 類型,所以執行 SafeSubscriber 的 setProducer() 方法,最終執行到 FromArrayProducer 對象中的 request() 方法,經過判斷,執行 fastPath() 方法,這個方法邏輯比較簡單,先是遍歷數組,執行 child 也就是 SafeSubscriber 的 onNext() 方法,遍歷結束後,執行 onCompleted() 方法,SafeSubscriber 是個包裝類,對應執行的是 initRxJava3() 中的 new Subscriber<String>() 對象中的 onNext() 和 onCompleted() 方法。

    private static void initRxJava4(){

        Observable
                .just("a", "b", "c", "d")
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {

                        return s + s;
                    }
                })
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        System.out.println(  "  onCompleted  " );
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        System.out.println(s + "   "  +  Thread.currentThread().getName());
                    }
                });
    }

這個方法在上面的基礎上添加了個 map 方法,它的作用是類型轉換,我們這裏僅僅是讓傳入的字符串由單個變爲雙個,來看它的原理,just() 方法創建了 Observable A,它裏面屬性 onSubscribe 是 OnSubscribeFromArray, OnSubscribeFromArray 中包含我們傳入的字符串數組;map() 方法是在 A 中又創建了一個 Observable 對象,命名爲B,屬性onSubscribe是
OnSubscribeMap 對象,它把 A 和 map() 中的類型轉換Func1作爲參數傳進構造方法中

    public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
        return create(new OnSubscribeMap<T, R>(this, func));
    }
    public static <T> Observable<T> create(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }


此時是在 B 中,繼續看 subscribe() 方法,我們知道,此時把 initRxJava4() 中的 new Subscriber<String>() 對象轉換爲 SafeSubscriber 類型,然後調用
OnSubscribeMap 的 call(subscriber) 方法,形參是 SafeSubscriber

    public void call(final Subscriber<? super R> o) {
        MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
        o.add(parent);
        source.unsafeSubscribe(parent);
    }


此時,source 是 Observable A,parent 構造方法中的兩個對象是 SafeSubscriber 和 map()中的類型轉換Func1,看看 unsafeSubscribe() 方法

    public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
        onSubscribe.call(subscriber);
        ...
    }

簡化後的代碼就是這樣,此時 onSubscribe 是 OnSubscribeFromArray ,subscriber 是 MapSubscriber,  call() 方法爲

    public void call(Subscriber<? super T> child) {
        child.setProducer(new FromArrayProducer<T>(child, array));
    }

有沒有很熟悉的感覺,這裏是老套路了,看看 MapSubscriber 中的方法

        @Override
        public void setProducer(Producer p) {
            actual.setProducer(p);
        }


此時 actual 是它構造方法傳進來的 SafeSubscriber,p 是 FromArrayProducer ,此時看父類中的 setProducer() 方法,上面分析過,先是 SafeSubscriber中的 setProducer() 方法,會走到 subscriber.setProducer(producer) 這一行代碼,此時 subscriber 代表的是 initRxJava4() 中的 new Subscriber<String>() 對象,然後繼續,這一次會執行到 producer.request(Long.MAX_VALUE) 這行代碼,此刻 producer 仍舊是 FromArrayProducer,上面已經有了,再次看它中的代碼

    static final class FromArrayProducer<T>
            extends AtomicLong
            implements Producer {

        final Subscriber<? super T> child;
        final T[] array;

        public FromArrayProducer(Subscriber<? super T> child, T[] array) {
            this.child = child;
            this.array = array;
        }

        @Override
        public void request(long n) {
            ...
            fastPath();
            ...
        }

        void fastPath() {
            final Subscriber<? super T> child = this.child;
            for (T t : array) {
                if (child.isUnsubscribed()) {
                    return;
                }
                child.onNext(t);
            }
            if (child.isUnsubscribed()) {
                return;
            }
            child.onCompleted();
        }

    }

child 是 MapSubscriber,也就是說會執行它的 onNext(t) 和 onCompleted() 方法,我們just()方法中數組數據,就是在這裏通過遍歷分發出去的,看看 MapSubscriber 的源碼

    static final class MapSubscriber<T, R> extends Subscriber<T> {
        final Subscriber<? super R> actual;
        final Func1<? super T, ? extends R> mapper;
        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;
            try {
                result = mapper.call(t);
            } catch (Throwable ex) {
                return;
            }
            actual.onNext(result);
        }
        
        @Override
        public void onCompleted() {
            actual.onCompleted();
        }
        
        @Override
        public void setProducer(Producer p) {
            actual.setProducer(p);
        }
    }

簡化後的代碼,actual 是 SafeSubscriber ,mapper 是 map()中的類型轉換Func1,都是通過構造方法傳遞進來的。此時 mapper.call(t) 執行了數據轉換,得到新的數據 result,然後調用了 SafeSubscriber 的 onNext(result) 方法,進而調用 initRxJava4()中的 new Subscriber<String>() 對象中的方法,onCompleted() 也是同樣的道理。


    private static void initRxJava5(){
        Observable
                .just("a b c", "12 3")
                .flatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String file) {
                        return Observable.from(file.split(" "));
                    }
                })

                .filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String s) {
                        return "a".equals(s);
                    }
                })

                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        return s + s;
                    }
                })

                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        System.out.println(  "  onCompleted  " );
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        System.out.println(s + "   "  +  Thread.currentThread().getName());
                    }
                });
    }

運行的結果是

a   main
  onCompleted  

這個方法中添加了轉換、攔截等功能,flatMap() 方法把 Observable 對象中的一個數組中的兩個對象,轉換爲了兩個 Observable 對象,每個對象中的數組內容是 "a b c" 、 "12 3" 這兩個字符串分別根據 " " 來拆分出來的新數組 {a,b,c} 、{12,3} ,通過 Observable.from() 生成對象;接着就是攔截功能,看看裏面的判斷,這裏是只有返回 true 纔會往下面執行,false的話就到此爲止了,繼續下一個數據;map() 中是個轉換,把字符串疊加;最後一個方法是打印。這個方法的源碼和前面一樣,都是通過包裝和回調,執行代碼。

RxJava 的初級用法就是回調和包裝類,單純這樣使用基本無用,本篇文章的介紹只是一個入門。

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