RxJava源码分析及Lift方法

Observable创建及订阅流程

RxJava源码分析及Lift方法_第1张图片

相关接口

ActionX 与 FuncX

ActionX –> 无返回值的回调接口

FuncX –> 带有返回值的回调接口

public interface Callable {
    V call() throws Exception;
}

观察者接口 - Observer

public interface Observer {

    /**
     * 正常终止,如果没有遇到错误,Observable在最后一次调用 
     * onNext之后调用此方法
     */
    void onCompleted();

    /**
     * 当Observable遇到错误或者无法返回期望的数据时会调用这个方
     * 法,这个调用会终止Observable,后续不会再调用onNext和
     * onCompleted,onError方法的参数是抛出的异常
     */
    void onError(Throwable e);

    /**
     * Observable调用这个方法发射数据,方法的参数就是Observable
     * 发射的数据  
     */
    void onNext(T t);

}

订阅者接口 - Subscription

此接口用于订阅者取消订阅及判定订阅者是否订阅

public interface Subscription {

    /**
     * 取消订阅
     */
    void unsubscribe();

    /**
     * 判读当前订阅者是否取消订阅
     * @return true:当前订阅者已取消订阅
     */
    boolean isUnsubscribed();

}

订阅者与被观察者通道容量 - Producer

此接口定义了一个订阅者与被观察者通道,request(long n)设定了订阅者可以接收观察者推送数据的数量。此设定仅对onNext()有效,对onComplete()和onError()方法无效。

public interface Producer {
    void request(long n);

}

Operator

核心类- 订阅者 Subscriber

概述

此类对接收到被观察者推送的数据,定义了系列的处理机制。订阅后,回调Observer接口

继承接口##

-- Observer,Subscription

SubscriptionList - 管理一组已订阅的订阅者

1.此对象含有一个Subscription的集合,这个集合用于管理未订阅的订阅者
2.核心方法
    1.构造方法
    2.添加订阅者 - add(Subscription s)

    public void add(final Subscription s) {
        // 该订阅者未订阅
        if (s.isUnsubscribed()) {
            return;
        }
        // 若当前订阅者组已订阅
        if (!unsubscribed) {
            synchronized (this) {
                if (!unsubscribed) {
                    List subs = subscriptions;
                    // 若当前订阅者组不存在,创建新的订阅者组
                    if (subs == null) {
                        subs = new LinkedList();
                        subscriptions = subs;
                    }
                    // 将新的已订阅的订阅者添加至已订阅的订阅者组
                    subs.add(s);
                    return;
                }
            }
        }
        // 若当前订阅者组未订阅,将预添加的订阅者取消订阅
        s.unsubscribe();
    }

    3.移除订阅者 - remove(final Subscription s)

        public void remove(final Subscription s) {
            // 当前订阅者组已订阅
            if (!unsubscribed) {
                boolean unsubscribe = false;
                synchronized (this) {
                    List subs = subscriptions;
                    if (unsubscribed || subs == null) {
                        return;
                    }
                    // 订阅者组是否将预移除的订阅者移除
                    unsubscribe = subs.remove(s);
                }
                if (unsubscribe) {
                    // 若订阅者已将预移除的订阅者移除,将此订阅者取消订阅
                    s.unsubscribe();
                }
            }
        }
    4.unsubscribeFromAll(Collection subscriptions) - 订阅者组中全部订阅者取消订阅核心方法,该方法的修饰符为private,并未对外部公开,仅在内部使用

    private static void unsubscribeFromAll(Collection subscriptions)
    {
        // 判断当前订阅者组是否有订阅者
        if (subscriptions == null) {
            return;
        }
        List es = null;
        for (Subscription s : subscriptions) {
            try {
                // 订阅者取消订阅
                s.unsubscribe();
            } catch (Throwable e) {
                if (es == null) {
                    es = new ArrayList();
                }
                // 捕获取消订阅异常
                es.add(e);
            }
        }
        Exceptions.throwIfAny(es);
    }
    5.unsubscribe() - 订阅者组取消订阅

    public void unsubscribe() {
        if (!unsubscribed) {
            List list;
            synchronized (this) {
                if (unsubscribed) {
                    return;
                }
                unsubscribed = true;
                list = subscriptions;
                // 将订阅者组置null,释放资源
                subscriptions = null;
            }
            // 订阅者组中的订阅者取消订阅
            unsubscribeFromAll(list);
        }
    }
    6.clear() - 清空订阅者组,同时将订阅者组中的订阅者全部取消订阅
    public void clear() {
        if (!unsubscribed) {
            List list;
            synchronized (this) {
                list = subscriptions;
                subscriptions = null;
            }
            unsubscribeFromAll(list);
        }
    }   
    7.hasSubscriptions() - 判断订阅者组中是否有订阅者
   public boolean hasSubscriptions() {
        if (!unsubscribed) {
            synchronized (this) {
                // 订阅者组已订阅
                // 订阅者集合非null且非空
                return !unsubscribed && subscriptions != null && !subscriptions.isEmpty();
            }
        }
        return false;
    }   

Subscriber

此对象中含有一个SubscriptionList和Producer用来管理设定订阅者对象。看SubscriptionList分析可知,SubscriptionList管理一系列已订阅的订阅者是否取消订阅,而Producer限定订阅者接收被观察者推送的数据。

构造方法

创建对象时,同时创建一个SubscriptionList,若SubscriptionList,存在不在创建。
protected Subscriber(Subscriber

暴漏外部的方法

0.此方法在订阅时调用,但此时被观察者并没有开始向订阅者推送数据。重写此方法可做订阅者初始化,例如设定Producer
public void onStart() {
    // do nothing by default
}

1.添加系列已订阅的订阅者
public final void add(Subscription s) {
    subscriptions.add(s);
}
2.判断是否取消订阅
public final boolean isUnsubscribed() {
    return subscriptions.isUnsubscribed();
}
3.取消订阅
public final void unsubscribe() {
    subscriptions.unsubscribe();
}
4.设定Producer
/**
 * 1.订阅者调用此方法可以设定Producer
 * 2.若订阅者没有调用此方法设定Producer,而且被观察者没有推送数据,此订阅者的Producer
 * 将使用默认值p.request(Long.MAX_VALUE)
 * 3.若订阅者没有调用此方法设定Producer,而且被观察者已推送N个数据,此订阅者的
 * Producer,将使用默认值p.request(N)
 */
public void setProducer(Producer p) {
    long toRequest;
    boolean passToSubscriber = false;
    synchronized (this) {
        toRequest = requested;
        // 设置producer
        producer = p;
        if (subscriber != null) {
            // NOT_SET默认值NOT_SET
            if (toRequest == NOT_SET) {
                // 若toRequest是默认值,意味着producer并未设置,告诉后续操作,设 
                // 定 producer
                passToSubscriber = true;
            }
        }
    }
    // 设定producer
    if (passToSubscriber) {
        subscriber.setProducer(producer);
    } else {
        // 若设定值为Long.MIN_VALUE,将默认设定Long.MAX_VALUE
        if (toRequest == NOT_SET) {
            producer.request(Long.MAX_VALUE);
        } else {
            producer.request(toRequest);
        }
    }
}


protected final void request(long n) {
    if (n < 0) {
        throw new IllegalArgumentException("number requested cannot be negative: " + n);
    } 

    Producer producerToRequestFrom = null;
    synchronized (this) {
        if (producer != null) {
            producerToRequestFrom = producer;
        } else {
            addToRequested(n);
            return;
        }
    }
    // after releasing lock (we should not make requests holding a lock)
    producerToRequestFrom.request(n);
}

protected final void request(long n) {
    if (n < 0) {
        throw new IllegalArgumentException("number requested cannot be negative: " + n);
    } 

    // if producer is set then we will request from it
    // otherwise we increase the requested count by n
    Producer producerToRequestFrom = null;
    synchronized (this) {
        if (producer != null) {
            producerToRequestFrom = producer;
        } else {
            addToRequested(n);
            return;
        }
    }
    // after releasing lock (we should not make requests holding a lock)
    producerToRequestFrom.request(n);
}

Observable

1.create(OnSubscribe f) 创建Observable,调用RxJavaHooks.onCreate(f)。其中RxJavaHooks类管理了Observable、调度(Scheduler)及生命周期相关联的工具类。
此类设定锁定状态,避免同步操作时的冲突。

首先看下Observable.create(OnSubscribe f)方法,其直接调用了构造方法生成了一个新的Observable对象,同时将我们创建的OnSubscribe对象保存在该Observable中的onSubscribe属性中。
// 构造方法
protected Observable(OnSubscribe f) {
this.onSubscribe = f;
}

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

在调用构造方法创建Observable前,RxJavaHooks.onCreate(f)方法对OnSubscribe对象处理过,而RxJavaHook类是用来干啥的呢?其实,RxJavaHook实际上是Observable, Single and Completable生命周期相关管理工具类。其内定义了系列Func1(T,R)静态常量,并在编译时,初始化。

  static {
        init();
  }

static void init() {
    onObservableStart = new Func2() {
        @Override
        public OnSubscribe call(Observable t1, OnSubscribe t2) {
            return RxJavaPlugins.getInstance().getObservableExecutionHook().onSubscribeStart(t1, t2);
        }
    };

    ***

    initCreate();
}

static void initCreate() {
    onObservableCreate = new Func1() {
        @Override
        public OnSubscribe call(OnSubscribe f) {
            return RxJavaPlugins.getInstance().getObservableExecutionHook().onCreate(f);
        }
    };

    ****
}

接下来看RxJavaHooks.onCreate(f)方法,其内 onObservableCreate调用了其回调返回了新的OnSubscribe。而在其会调中是通过RxJavaPlugins.getInstance().getObservableExecutionHook().onCreate(f)返回OnSubscribe。

public class RxJavaPlugins {
    private final static RxJavaPlugins INSTANCE = new RxJavaPlugins();

    private final AtomicReference observableExecutionHook = new AtomicReference();

    ***

    public static RxJavaPlugins getInstance() {
        return INSTANCE;
    }


    public RxJavaObservableExecutionHook getObservableExecutionHook() {
        if (observableExecutionHook.get() == null) {
            Object impl = getPluginImplementationViaProperty(RxJavaObservableExecutionHook.class, System.getProperties());
            if (impl == null) {lize with default 
                observableExecutionHook.compareAndSet(null, RxJavaObservableExecutionHookDefault.getInstance());he winner will always get returned
            } else {
                observableExecutionHook.compareAndSet(null, (RxJavaObservableExecutionHook) impl);
            }
        }
        return observableExecutionHook.get();
    }

    *** 

}

文档中是这么介绍的RxJavaPlugins,RxJavaPlugins实现了基于优先级顺序的全局注册和正确检索。
在RxJavaPlugins中,使用AtomicReference引用原始类型,作用于observableExecutionHook对象。保证了当某线程修改observableExecutionHooke的值时,其他线程看到的observableExecutionHook值都是最新的,即修改之后的值。

public abstract class RxJavaObservableExecutionHook { // NOPMD 

    ***

    public  OnSubscribe onCreate(OnSubscribe f) {
        return f;
    }

    ***
}

最后看下RxJavaObservableExecutionHook.onCreate(OnSubscribe f)方法,其直接返回了
之前传入的OnSubscribe对象,并未做修改。大家都知道是,RxJava是在处理多线程并发数据的,通过AtomicReference的原子操作,保持了OnSubscribe都是最新的。

到这里,一个Observable对象创建结束了,费劲千辛万苦,只是为了将我们创建的onSubscribe对象保存在Observable的onSubscribe属性中。回过头来看,onSubscribe又是啥东西?

public interface OnSubscribe extends Action1> {
    // cover for generics insanity
}

public interface Action1 extends Action {
    void call(T t);
}

其实,interface OnSubscribe只是接口,继承于Action1.在Aciton1中,只有一个方法call(T t)。在文档中,这么说的,在Observable.subscribe即在Observable被订阅时回调此方法。而Action1

lift

lift方法是RxJava中实现自定义operator的关键,其参数值便是自定义的Operator。下面先看OnSubscribeLift这个类,这个类中有两个属性parent和operator,parent属性不用多说,就是原OnSubscribe,operator就是我们自定义的operator.

public final class OnSubscribeLift implements OnSubscribe {

    final OnSubscribe parent;

    final Operator operator;

    public OnSubscribeLift(OnSubscribe parent, Operator operator) {
        this.parent = parent;
        this.operator = operator;
    }

    ***
}

而Operator接口是继承了接口Func1,返回了目标的Subscriber。先说Func1这个回调接口,这个接口参数只要一个call(T)方法,在回调时会返回一个R类型的值。

public interface Func1 extends Function {
    R call(T t);
}

lift方法实际上创建了一个新的OnSubscribe对象,暂时命名为chilld。在观察者订阅时,其回调的应该是child的call方法。

public void call(Subscriber o) {
    try {
        Subscriber st = RxJavaHooks.onObservableLift(operator).call(o);
        try {
            // new Subscriber created and being subscribed with so 'onStart' it
            st.onStart();
            parent.call(st);
        } catch (Throwable e) {
            // localized capture of errors rather than it skipping all operators 
            // and ending up in the try/catch of the subscribe method which then
            // prevents onErrorResumeNext and other similar approaches to error handling
            Exceptions.throwIfFatal(e);
            st.onError(e);
        }
    } catch (Throwable e) {
        Exceptions.throwIfFatal(e);
        // if the lift function failed all we can do is pass the error to the final Subscriber
        // as we don't have the operator available to us
        oonError(e);
    }
}

细看OnSubscribeLift中call()方法的源码,call方法中接收观察者创建的Subscriber对象o,然后通过自定义operator返回了一个新的Subscriber对象st,接着调用了parent.call(st)方法,将st创递给parent。下面一个两个流程图解析了回调过程和发射后传递流程。
RxJava源码分析及Lift方法_第2张图片

你可能感兴趣的:(RxJava)