RxRelay源碼解析

RxRelay源碼解析:
Relays 是既是Observable也是Consumer的RxJava 類型,由於沒有onComplete 或 onError,所以發生異常時不會觸發下游的終止狀態,不會拋出異常。

	 //接收訂閱之後數據
        Relay relay = PublishRelay.create().toSerialized();
        //接受訂閱之前一個和之後數據
        Relay relay = BehaviorRelay.createDefault("Hello World");
        //不管何時訂閱,發送所有數據
        Relay relay = ReplayRelay.create(5).toSerialized();
/**
 * 隊列,用於存儲帶發射的值
 */
class AppendOnlyLinkedArrayList<T> {

    private final int capacity;     //容量
    private final Object[] head;    //用於存放值
    private Object[] tail;
    private int offset;     //數組指針

    /**
     * 指定容量,初始化數組爲容量大小
     */
    AppendOnlyLinkedArrayList(int capacity) {
        this.capacity = capacity;
        this.head = new Object[capacity + 1];
        this.tail = head;
    }

    /**
     * 向隊列插入值
     */
    void add(T value) {
        final int c = capacity;
        int o = offset;
        //若容量滿了,創建新數組tail,新數組開始位置指向head末尾,向新數組tail[0]插入值
        if (o == c) {
            Object[] next = new Object[c + 1];
            tail[c] = next;
            tail = next;
            o = 0;
        }
        //容量未滿,按偏移量插入值
        tail[o] = value;
        offset = o + 1;
    }

    /**
     * 自定義條件
     */
    public interface NonThrowingPredicate<T> extends Predicate<T> {
        @Override
        boolean test(T t);
    }

    /**
     * 便利隊列中所有數組,遇到空或返回條件爲真退出
     */
    @SuppressWarnings("unchecked")
    void forEachWhile(NonThrowingPredicate<? super T> consumer) {
        Object[] a = head;
        final int c = capacity;
        while (a != null) {
            for (int i = 0; i < c; i++) {
                Object o = a[i];
                if (o == null) {
                    break;
                }
                if (consumer.test((T)o)) {
                    break;
                }
            }
            //若數組便利完成,便利下一個數組,a[c]指向下一個數組開頭
            a = (Object[])a[c];
        }
    }

    /**
     * 遍歷隊列中所有數組,回掉值給Relay的accept方法,遇到空值則退出
     * @param observer
     * @return
     */
    @SuppressWarnings("unchecked")
    boolean accept(Relay<? super T> observer) {
        Object[] a = head;
        final int c = capacity;
        while (a != null) {
            for (int i = 0; i < c; i++) {
                Object o = a[i];
                if (o == null) {
                    break;
                }
                //回掉值給Relay的accept方法
                observer.accept((T) o);
            }
            a = (Object[])a[c];
        }
        return false;
    }
}
public abstract class Relay<T> extends Observable<T> implements Consumer<T> {

    /** 接受數據 */
    @Override public abstract void accept(T value); // Redeclare without checked exception.

    public abstract boolean hasObservers();

    /** 封裝Relay並序列化調用 */
    @NonNull
    @CheckReturnValue
    public final Relay<T> toSerialized() {
        if (this instanceof SerializedRelay) {
            return this;
        }
        return new SerializedRelay<T>(this);
    }
}
/**
 * 序列化Relay,封裝一次Relay
 */
public class SerializedRelay<T> extends Relay<T> {

    private final Relay<T> actual;

    //表示發射正在進行,由這個控制
    private boolean emitting;

    //隊列
    private AppendOnlyLinkedArrayList<T> queue;


    SerializedRelay(final Relay<T> actual) {
        this.actual = actual;
    }

    /**
     * 形成訂閱
     */
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        actual.subscribe(observer);
    }


    /**
     * 接受來自隊列的值
     */
    @Override
    public void accept(T value) {
        synchronized (this) {
            //正在發射狀態,就先添加值到隊列
            if (emitting) {
                AppendOnlyLinkedArrayList<T> q = queue;
                if (q == null) {
                    q = new AppendOnlyLinkedArrayList<T>(4);
                    queue = q;
                }
                q.add(value);   //添加到隊列
                return;
            }
            emitting = true;
        }
        //未在發射狀態,直接回掉值給Relay的accept方法
        actual.accept(value);
        emitLoop();
    }

    /** 遍歷隊列,回掉值給Relay的accept方法 */
    private void emitLoop() {
        for (;;) {
            AppendOnlyLinkedArrayList<T> q;
            synchronized (this) {
                q = queue;
                //爲空說明已發送完成
                if (q == null) {
                    emitting = false;
                    return;
                }
                queue = null;
            }
            //遍歷隊列q中所有數組,回掉值給Relay的accept方法,遇到空值則退出
            q.accept(actual);
        }
    }

    @Override
    public boolean hasObservers() {
        return actual.hasObservers();
    }
}
/**
 * 發送訂閱之後數據
 * @param <T>
 */
public class PublishRelay<T> extends Relay<T> {

    //一個空的訂閱者數組,以避免一直分配它
    @SuppressWarnings("rawtypes")
    static final PublishDisposable[] EMPTY = new PublishDisposable[0];

    //原子引用,使得多線程操作的是同一個對象
    final AtomicReference<PublishDisposable<T>[]> subscribers;

    /**
     * 生成一個原子引用的訂閱者數組EMPTY
     */
    @CheckReturnValue
    @NonNull
    public static <T> PublishRelay<T> create() {
        return new PublishRelay<T>();
    }

    /**
     * 原子引用訂閱者數組EMPTY
     */
    @SuppressWarnings("unchecked")
    PublishRelay() {
        subscribers = new AtomicReference<PublishDisposable<T>[]>(EMPTY);
    }

    @Override
    protected void subscribeActual(Observer<? super T> t) {
        PublishDisposable<T> ps = new PublishDisposable<T>(t, this);
        t.onSubscribe(ps);
        add(ps);
        // if cancellation happened while a successful add, the remove() didn't work
        // so we need to do it again
        if (ps.isDisposed()) {
            remove(ps);
        }
    }

    /**
     * 創建一個比原數組大1的數組,複製原數組到新數組,添加訂閱者ps到末尾
     */
    void add(PublishDisposable<T> ps) {
        for (;;) {
            //得到原子引用對象訂閱者數組EMPTY
            PublishDisposable<T>[] a = subscribers.get();
            int n = a.length;
            //創建比EMPTY大1的數組,剛開始EMPTY爲0,大小從1開始,2,3...
            @SuppressWarnings("unchecked")
            PublishDisposable<T>[] b = new PublishDisposable[n + 1];
            //從索引0複製a數組到b數組,放置起始索引0,複製n項
            System.arraycopy(a, 0, b, 0, n);
            //新添加的訂閱者ps放置在最末尾
            b[n] = ps;

            if (subscribers.compareAndSet(a, b)) {
                return;
            }
        }
    }

    /**
     *刪除數組中指定訂閱者
     */
    @SuppressWarnings("unchecked")
    void remove(PublishDisposable<T> ps) {
        for (;;) {
            PublishDisposable<T>[] a = subscribers.get();
            if (a == EMPTY) {
                return;
            }

            int n = a.length;
            int j = -1;
            //找到待刪除訂閱者索引,賦值給j,退出循環
            for (int i = 0; i < n; i++) {
                if (a[i] == ps) {
                    j = i;
                    break;
                }
            }

            if (j < 0) {
                return;
            }

            PublishDisposable<T>[] b;

            if (n == 1) {
                b = EMPTY;
            } else {
                //創建一個大小減1的數組
                b = new PublishDisposable[n - 1];
                //複製a中前j項到b,要刪除的索引爲j(第j+1個)
                System.arraycopy(a, 0, b, 0, j);
                //再複製a中j+2開始項之後到b
                System.arraycopy(a, j + 1, b, j, n - j - 1);
            }
            //若原子引用對象和a是同一個對象,用b替換a
            if (subscribers.compareAndSet(a, b)) {
                return;
            }
        }
    }

    @Override
    public void accept(T value) {
        if (value == null) throw new NullPointerException("value == null");
        for (PublishDisposable<T> s : subscribers.get()) {
            //發射value給訂閱者
            s.onNext(value);
        }
    }

    @Override
    public boolean hasObservers() {
        return subscribers.get().length != 0;
    }

    /**
     * 封裝訂閱者, 跟蹤其請求並進行取消操作,以便從當前訂閱者數組中刪除自己.
     */
    static final class PublishDisposable<T> extends AtomicBoolean implements Disposable {

        private static final long serialVersionUID = 3562861878281475070L;

        final Observer<? super T> downstream;

        final PublishRelay<T> parent;

        PublishDisposable(Observer<? super T> actual, PublishRelay<T> parent) {
            this.downstream = actual;
            this.parent = parent;
        }

        public void onNext(T t) {
            //當前引用對象爲fals,即訂閱狀態,發射這個t
            if (!get()) {
                downstream.onNext(t);
            }
        }

        @Override
        public void dispose() {
            //設置引用對象爲true
            if (compareAndSet(false, true)) {
                parent.remove(this);
            }
        }

        @Override
        public boolean isDisposed() {
            return get();   //當前引用對象的boolean值
        }
    }
}

其他兩個大同小異。

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