RxJava源码解析2.2.6版本

前言

上一篇文章分析了okhttp的源码,因为一个网络请求框架一般都是使用rxjava+okhttp+retrofit进行封装,所以现在对rxjava的源码进行解析。

观察者模式介绍

众所周知,rxjava是使用的观察者的模式,观察者模式是一个使用率非常高的模式,这个模式的一个重要的作用就是解耦,将被观察者和观察者解耦,使得他们之间的依赖性更小,甚至毫无依赖。

观察者模式的定义

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有的依赖于他的对象都会得到通知并被自动更新。

Android中的观察者

在分析rxjava前,先对Android中的观察者模式做一个简单的分析,对观察者模式有一个简单的了解。

简单使用

下面我们来简单模拟下程序员订阅博文的发布---订阅过程。

一、程序员是观察者

/**
 * 程序员是观察者
 */
public class Coder implements Observer {
    private String name;

    public Coder(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        Log.e("TAG","hi,"+name+"你观察的方法(订阅)更新啦"+",更新内容:"+arg);
    }

    @Override
    public String toString() {
        return "Coder{" +
                "name='" + name + '\'' +
                '}';
    }
}

二、订阅的博文网站是被观察者

/**
 * 这个类代表的是订阅的博文网站,这个是被观察的对象,当它有更新的使用所有的观察者(这里是程序员)都会接收到相应的消息
 */
public class DevTech extends Observable {
    void postNewPublic(String context){
        setChanged();
        notifyObservers(context);
    }
}

三、测试代码

在Android中测试的话,定义一个按钮进行触发,代码如下

DevTech devTech=new DevTech();
Coder coder=new Coder("程序员1");
Coder coder2=new Coder("程序员2");
Coder coder3=new Coder("程序员3");
Coder coder4=new Coder("程序员4");
devTech.addObserver(coder);
devTech.addObserver(coder2);
devTech.addObserver(coder3);
devTech.addObserver(coder4);
devTech.postNewPublic("我是你观察的博文,给你发送更新啦");

输出结果:

RxJava源码解析2.2.6版本_第1张图片

可以看到所有的订阅了博文的用户都接收到了消息,一对多的订阅----发布系统就完成了。

Observer和Observable是JDK中的内置类型,可见观察者是非常重要的,这里的Observer是抽象的观察者角色,Coder扮演的是具体的观察者的角色,Observable对应的是抽象主题角色,DevTech则是具体的主题角色。Coder是具体的观察者,他们订阅了DevTech这个具体的可观察对象,当DevTech进行更新时,会遍历所有的观察者(这里是coder),然后给这些观察者发布一个更新的消息,即调用Coder中的update方法,这样就达到了一对多的通知功能,在这个过程中,通知系统都是依赖Observer和Observable这些抽象类,因此,对于Coder和DevTech来说,完全没有耦合,保证了系统的灵活性,可拓展性。

在Android的源码中也使用到了观察者模式,比如我们经常使用的recycleview中的adapter,这里也是使用了观察者的模式进行数据的更新,还有广播等,这里就不介绍了。

RxJava简单使用

Observable observable = Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        emitter.onNext("发送消息");
        emitter.onNext("发送消息1");
        emitter.onNext("发送消息2");
        emitter.onComplete();
    }
});
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(mStringObserver);
Observer mStringObserver = new Observer() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.e("TAG", "onSubscribe");
    }

    @Override
    public void onNext(String s) {
        Log.e("TAG", s);
        Log.e("TAG", "onNext");
    }

    @Override
    public void onError(Throwable e) {
        Log.e("TAG", "onError");
    }

    @Override
    public void onComplete() {
        Log.e("TAG", "onComplete");
    }
};

或者也可以一步到位:

Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        emitter.onNext("发送消息");
        emitter.onNext("发送消息1");
        emitter.onNext("发送消息2");
        emitter.onComplete();
    }
}).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(new Observer() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.e("TAG", "onSubscribe");
    }

    @Override
    public void onNext(String s) {
        Log.e("TAG", s);
        Log.e("TAG", "onNext");
    }

    @Override
    public void onError(Throwable e) {
        Log.e("TAG", "onError");
    }

    @Override
    public void onComplete() {
        Log.e("TAG", "onComplete");
    }
});

输出结果:

RxJava源码解析2.2.6版本_第2张图片

使用步骤与源码分析:

第一步:

创建Observable(被观察者)

Observable observable = Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        emitter.onNext("发送消息");
        emitter.onNext("发送消息1");
        emitter.onNext("发送消息2");
        emitter.onComplete();
    }
});

源码:

@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static  Observable create(ObservableOnSubscribe source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}
public static  T requireNonNull(T object, String message) {
    if (object == null) {
        throw new NullPointerException(message);
    }
    return object;
}
/**
 * Calls the associated hook function.
 * @param  the value type
 * @param source the hook's input value
 * @return the value returned by the hook
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static  Observable onAssembly(@NonNull Observable source) {
    Function f = onObservableAssembly;
    if (f != null) {
        return apply(f, source);
    }
    return source;
}
class ObservableCreate extends Observable
 abstract class Observable implements ObservableSource

从源码中,我们可以看到,Observable对象调用了 create(…) 方法返回的是一个 observable 对象,其实最终返回的是 ObservableCreate. 
RxJavaPlugins.onAssembly 只是相当于 hook 而已。

第二步:

创建Observer(观察者)

Observer mStringObserver = new Observer() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.e("TAG", "onSubscribe");
    }

    @Override
    public void onNext(String s) {
        Log.e("TAG", s);
        Log.e("TAG", "onNext");
    }

    @Override
    public void onError(Throwable e) {
        Log.e("TAG", "onError");
    }

    @Override
    public void onComplete() {
        Log.e("TAG", "onComplete");
    }
};

第三步:

订阅:

observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(mStringObserver);
源码分析:
abstract class Observable implements ObservableSource

在Observable类中可以看到Observable实现了ObservableSource接口,重写了ObservableSource接口中的subscribe()方法。

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

        ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

        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(…),该方法是个抽象方法,会调用实现类中的方法。

protected abstract void subscribeActual(Observer observer);

实现类ObservableCreate中的方法:

@Override
protected void subscribeActual(Observer observer) {
    CreateEmitter parent = new CreateEmitter(observer);
    observer.onSubscribe(parent);

    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}

最终会调用source.subscribe(parent);方法,source是在创建Observable时传的ObservableOnSubscribe对象,下面看看ObservableOnSubscribe类:

public interface ObservableOnSubscribe {

    /**
     * Called for each Observer that subscribes.
     * @param emitter the safe emitter instance, never null
     * @throws Exception on error
     */
    void subscribe(@NonNull ObservableEmitter emitter) throws Exception;
}

所以最终会回调subscribe()方法。

然后在subscribe(ObservableEmitter emitter)方法中进行消息的处理操作。

所以,在下面的subscribe()方法进行了数据的发送。

Observable observable = Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        emitter.onNext("发送消息");
        emitter.onNext("发送消息1");
        emitter.onNext("发送消息2");
        emitter.onComplete();
    }
});

ObservableEmitter类

public interface ObservableEmitter extends Emitter {

    void setCancellable(@Nullable Cancellable c);

    boolean isDisposed();

    @NonNull
    ObservableEmitter serialize();

    boolean tryOnError(@NonNull Throwable t);
}

而CreateEmitter是ObservableEmitter的实现类,所最终会调用CreateEmitter类中的方法进行消息的处理。

CreateEmitter类

static final class CreateEmitter
extends AtomicReference
implements ObservableEmitter, Disposable {

    private static final long serialVersionUID = -3434801548987643227L;

    final Observer observer;

    CreateEmitter(Observer observer) {
        this.observer = observer;
    }

    @Override
    public void onNext(T t) {
        if (t == null) {
            onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
            return;
        }
        if (!isDisposed()) {
            observer.onNext(t);
        }
    }

    @Override
    public void onError(Throwable t) {
        if (!tryOnError(t)) {
            RxJavaPlugins.onError(t);
        }
    }

    @Override
    public boolean tryOnError(Throwable t) {
        if (t == null) {
            t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
        }
        if (!isDisposed()) {
            try {
                observer.onError(t);
            } finally {
                dispose();
            }
            return true;
        }
        return false;
    }

    @Override
    public void onComplete() {
        if (!isDisposed()) {
            try {
                observer.onComplete();
            } finally {
                dispose();
            }
        }
    }

    @Override
    public void setDisposable(Disposable d) {
        DisposableHelper.set(this, d);
    }

    @Override
    public void setCancellable(Cancellable c) {
        setDisposable(new CancellableDisposable(c));
    }

    @Override
    public ObservableEmitter serialize() {
        return new SerializedEmitter(this);
    }

    @Override
    public void dispose() {
        DisposableHelper.dispose(this);
    }

    @Override
    public boolean isDisposed() {
        return DisposableHelper.isDisposed(get());
    }

    @Override
    public String toString() {
        return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
    }
}

下面我们继续分析,我们只有看onNext()方法。

@Override
public void onNext(T t) {
    if (t == null) {
        onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
        return;
    }
    if (!isDisposed()) {
        observer.onNext(t);
    }
}

从上面方法中可以看出,如果没有被disposed ,则会调用 observer.onNext(t) 方法,observer 是最终的订阅者,将数据传个订阅者。这里将observable 与 observer 联系起来。

Observer mStringObserver = new Observer() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.e("TAG", "onSubscribe");
    }

    @Override
    public void onNext(String s) {
        Log.e("TAG", s);
        Log.e("TAG", "onNext");
    }

    @Override
    public void onError(Throwable e) {
        Log.e("TAG", "onError");
    }

    @Override
    public void onComplete() {
        Log.e("TAG", "onComplete");
    }
};

所以,最终所以订阅了该对象的订阅者都会接受到消息。

RxJava线程调度

在分析上面的代码中,使用到了

observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(mStringObserver);

这里就进行了进程的调度操作。

Schedulers:调度器

subscribeOn(Schedulers.io()),这里将数据的发射放在 IO 线程中。

如果需要再Android中的UI使用到该数据,则需要更新UI,我们都知道更新UI是需要再Android的主线程中的,所以如果需要更新Android的UI,就需要把现场调度到Android中的主线程,RxJava没有提供调度到Android中主线程的方法,所以我们需要一个方法进行调度,在RxAndroid中就提供了一个方法,可以把线程调度到Android的主线程,然后进行UI的更新操作,项目看看RxAndroid中的进程调度方法:

public final class AndroidSchedulers {
    private static final AtomicReference INSTANCE = new AtomicReference<>();

    private final Scheduler mainThreadScheduler;

    private static AndroidSchedulers getInstance() {
        for (;;) {
            AndroidSchedulers current = INSTANCE.get();
            if (current != null) {
                return current;
            }
            current = new AndroidSchedulers();
            if (INSTANCE.compareAndSet(null, current)) {
                return current;
            }
        }
    }

    private AndroidSchedulers() {
        RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();

        Scheduler main = hook.getMainThreadScheduler();
        if (main != null) {
            mainThreadScheduler = main;
        } else {
            mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());
        }
    }

    /** A {@link Scheduler} which executes actions on the Android UI thread. */
    public static Scheduler mainThread() {
        return getInstance().mainThreadScheduler;
    }

    /** A {@link Scheduler} which executes actions on {@code looper}. */
    public static Scheduler from(Looper looper) {
        if (looper == null) throw new NullPointerException("looper == null");
        return new LooperScheduler(looper);
    }

    /**
     * Resets the current {@link AndroidSchedulers} instance.
     * This will re-init the cached schedulers on the next usage,
     * which can be useful in testing.
     */
    @Experimental
    public static void reset() {
        INSTANCE.set(null);
    }
}

从源码中,我们可以看到,AndroidSchedulers中有一个方法mainThread()方法中返回了一个Scheduler对象,而这个Scheduler对象就是Android的主线程。

把线程调度到主线程的方法:

observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mStringObserver);

至此,就可以在Observer中的onNext()方法中获取想应的数据然后进行UI更新操作了。

附上解析demo:https://github.com/freakcsh/Rxjava

 

 

你可能感兴趣的:(源码解析)