RxJava源码分析

本文介绍了RxJava的基本使用,并通过一个简单示例详细解释了RxJava中 observable 的创建、转换和订阅过程。文章重点在于源码分析,探讨了操作符如何互相调用以传递事件,以及Observer在事件传递中的作用。虽然没有涉及线程切换和背压机制,但对于理解RxJava的工作原理有很好的帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 RxJava的鼎鼎大名相信Android开发的同学都非常熟悉了,其实不仅仅有RxJava,还有RxJs,RxKotlin等等一系列。可以说Rx并不是一种局限于Android的框架,Rx是一种思想,我们深入了解了RxJava,同样会加深我们对其他Rx系列的认知。

RxJava的使用

 先来看一个简单的例子。衍变自Android RxJava实际应用教学:你该什么时候使用RxJava?这篇文章

        //创建一个被观察者observable1 
        Observable<Long> observable1 = Observable.create(new ObservableOnSubscribe<Long>() {//ObservableCreate
            @Override
            public void subscribe(ObservableEmitter<Long> emitter) throws Exception {
                emitter.onNext(10L);
                emitter.onComplete();
            }
        });
        //创建一个被观察者observable2
        final Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {//ObservableCreate
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("test");
                emitter.onComplete();
            }
        });
        observable1
                 //调用observable1中观察者的onNext方法
                .doOnNext(new Consumer<Long>() {//ObservableDoOnEach
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.i(TAG, "observable1 accept: " + aLong);
                    }
                })
                 //ObservableSubscribeOn,通过subscribeOn可以切换被观察者所在的线程,如subscribeOn(Schedulers.io())就代表被观察者会在IO线程执行
                .subscribeOn(Schedulers.io())
                 //进行Observable转换,将observable1转换成observable2
                .flatMap(new Function<Long, ObservableSource<String>>() {//转换操作,ObservableFlatMap
                    @Override
                    public ObservableSource<String> apply(Long aLong) throws Exception {
                        return observable2;
                    }
                })
                )
                 //ObservableObserveOn,通过observeOn可以切换观察者所在的线程,如observeOn(AndroidSchedulers.mainThread())就代表观察者会在主线程执行
                .observeOn(AndroidSchedulers.mainThread()
                 //订阅观察者
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.i(TAG, "onSubscribe: ");
                    }

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

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

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

 在RxJava中,每个操作符对应一个继承自Observable的对象。

createdoOnNextsubscribeOnflatMapobserveOn
ObservableCreateObservableDoOnEachObservableSubscribeOnObservableFlatMapObservableObserveOn

 整个流程是从create操作符开始的,分别创建两个Observable对象:observable1与observable2。observable1对应的类型是Long,observable2对应的类型是String。create创建了一个对象ObservableCreate,以observable1为例:

    //创建一个ObservableCreate对象并返回,ObservableCreate继承自Observable
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }
    //ObservableCreate的实现
    public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;
    //将ObservableOnSubscribe赋给source 
    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        //包装传递过来的Observer对象,采用了装饰设计模式
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);
        try {
            //订阅,连接Observable与Observer
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
    ...
	}

 调用doOnNext方法就会创建了一个ObservableDoOnEach对象并把当前Observable——observable1传递给ObservableDoOnEach

    //创建ObservableDoOnEach对象并返回
    public final Observable<T> doOnNext(Consumer<? super T> onNext) {
        return doOnEach(onNext, Functions.emptyConsumer(), Functions.EMPTY_ACTION, Functions.EMPTY_ACTION);
    }
    private Observable<T> doOnEach(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Action onAfterTerminate) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableDoOnEach<T>(this, onNext, onError, onComplete, onAfterTerminate));
    }
    public final class ObservableDoOnEach<T> extends AbstractObservableWithUpstream<T, T> {
    ...
    //将ObservableCreate赋给source
    public ObservableDoOnEach(ObservableSource<T> source, Consumer<? super T> onNext,
                              Consumer<? super Throwable> onError,
                              Action onComplete,
                              Action onAfterTerminate) {
        super(source);
        this.onNext = onNext;
        this.onError = onError;
        this.onComplete = onComplete;
        this.onAfterTerminate = onAfterTerminate;
    }
    //将Observer包装成DoOnEachObserver并赋给ObservableCreate
    @Override
    public void subscribeActual(Observer<? super T> t) {
        //订阅,连接Observable与Observer
        source.subscribe(new DoOnEachObserver<T>(t, onNext, onError, onComplete, onAfterTerminate));
    }
    ...
    }

 调用ObservableDoOnEachsubscribeOn则会创建一个ObservableSubscribeOn对象,在ObservableSubscribeOn中会将任务添加到子线程中,也就是说subscribeOn能切换Observable所在的线程

    //创建`ObservableSubscribeOn`对象
    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }
    public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    //将ObservableDoOnEach赋给source
    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }
    //此方法主要是将Observer包装成SubscribeOnObserver并塞进任务,然后添加到线程池,等待子线程的执行
    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
        s.onSubscribe(parent);
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }
    ...
    //当子线程执行时,将SubscribeOnObserver传递给ObservableDoOnEach
    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            //订阅,连接Observable与Observer
            source.subscribe(parent);
        }
    }
    }

 调用flatMap会创建ObservableFlatMap对象,ObservableFlatMap主要就是一个转换功能,将一个Observable对象转换成另外一个Observable对象并返回,上面示例中就是将observable1转换成observable2。

    //创建ObservableFlatMap对象
    public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
    }
    public final class ObservableFlatMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    ...
    //将ObservableSubscribeOn赋给source
    public ObservableFlatMap(ObservableSource<T> source,
            Function<? super T, ? extends ObservableSource<? extends U>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
        ...
    }
    //将Observer包装成MergeObserver传递给ObservableSubscribeOn
    @Override
    public void subscribeActual(Observer<? super U> t) {
        if (ObservableScalarXMap.tryScalarXMapSubscribe(source, t, mapper)) {
            return;
        }
        //订阅,连接Observable与Observer
        source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
    }
    ...
    }

 将observable1转换成observable2后,调用observeOn方法,并创建ObservableObserveOn对象,ObservableObserveOn主要是切换Observe所在的线程,在Android中,可通过此操作符切换为主线程。

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    //将ObservableFlatMap赋给source
    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }
    //将Observer包装成ObserveOnObserver再传递给ObservableFlatMap
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();
            //订阅,连接Observable与Observer
            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }
    ...
    }

 最后ObservableObserveOn再通过subscribe来与Observer连接起来。

    public final void subscribe(Observer<? super T> observer) {
        ...
        try {
            ...
            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            ...
            throw npe;
        }
    }

 在subscribe方法中会调用subscribeActual这个方法,该方法是不是很熟悉,虽然在ObservableCreate、ObservableDoOnEach、ObservableSubscribeOn、ObservableFlatMap、ObservableObserveOn中都有不同实现,但都会调用subscribe方法。就这样互相调用,从而让第一个Observable对象ObservableCreate发射事件。再将事件一层一层的传递下去。整体流程如图,以next为例
在这里插入图片描述

 图中最上面的Observer就是我们自己创建的,在里面可以拿到返回的结果。
 关于RxJava源码分析到此就结束了,本文未涉及到RxJava的线程切换及背压,关于线程切换可以阅读RxJava之线程切换原理分析

【参考资料】
RxJava2源码分析
RxJava2 源码分析(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值