RxJava之just与from源码解读

来源:互联网 发布:解题软件 编辑:程序博客网 时间:2024/04/29 20:18

上一节我们主要讲的是RxJava的入门之create的源码解读,让我们对RxJava有了初步的认识,本来这篇文章应该前些天写的,但是由于最近工作比较忙,今天晚上,不知道怎么的失眠睡不着,于是乎想起来做点什么,便有了现在的这篇文章。好,废话不多说,我们现在开始进入正题。
首先我们来看下下面这些代码:

public static void just() {        List<Integer> items = new ArrayList<>();        items.add(1);        items.add(10);        items.add(100);        items.add(200);        Observable.just(items)                .subscribe(new Observer<List<Integer>>() {                    @Override                    public void onCompleted() {                        Log.d("test", "OnComplete");                    }                    @Override                    public void onError(Throwable e) {                        Log.d("test", e.toString());                    }                    @Override                    public void onNext(List<Integer> integers) {                        for (int i = 0; i <integers.size();i++){                 Log.d("test",String.valueOf(integers.get(i)));                        }                    }                });    }    public static void from() {        List<Integer> items = new ArrayList<>();        items.add(1);        items.add(10);        items.add(100);        items.add(200);        Observable.from(items)                .subscribe(new Observer<Integer>() {                    @Override                    public void onCompleted() {                        Log.d("test", "OnComplete");                    }                    @Override                    public void onError(Throwable e) {                        Log.d("test", e.toString());                    }                    @Override                    public void onNext(Integer integers) {                        Log.d("test", "Item is " +       String.valueOf(integers));                    }                });    }

上面主要贴的是一个just函数与一个from函数,代码上大家看下他们具体有什么差别。

  1. 我们看到传入的都是一个list,所以打印出来的内容都是一样的,但是默认最后都会执行onComplete这个方法,打印出OnComplete字符串。
  2. 其次subscribe这个方法中的入参just是一个list类型,from是一个Integer类型,这说明当需要循环完list中的数据时,from需要调用4次onNext,而just之需要调用一次OnNext(以本例子中list中有4个字符串为例),所以当我们需要在一个界面展示一个list的时候,我们就应该使用just,这样只会刷新一次界面,from的话会调用4次,最后展示的可能就不是我们想要的结果的列表。
    总结了上面的结论,我们再来看下这两个函数具体是怎么实现的?
    首先来说下from,看下图:

    这里写图片描述

我们看到from中的入参是一个Interable类型的,而很多的集合类都实现了这一个接口,比如我们前面举例的list,继承自Collection,而Collection是继承自Interable的。
当我们调用from的时候,我们new了一个OnSubscribeFromIterable对象,我们知道实现OnSubscribe接口的类有好多个,OnSubscribeFromIterable便是其中的一个,调用new这个方法,我们只是把我们创建出来的list保存到了一个变量当中,这里暂且取名为it,然后在from这个方法里面又调用了一个create的方法,其实这个方法,和我们上一张讲过的调用的是同一个方法,如下图所示:

这里写图片描述

调用上面的这个方法, 只是传入一个OnSubscribe对象保存在了一个名叫OnSubscribe的变量当中,

接下来我们再来分析subScribe()过程,
和上一章讲的一样,当我们调用这个方法的时候,如下图:

这里写图片描述

仔细的观察这个方法,我们看到当我们传入我们创建的obServer的时候,他只是重新创建了一个Subscriber对象,而这个对象是继承自Observer的,我们暂且把自己创建的叫observer1,新创建的叫做observer2,看下subscribe具体的实现过程:

 private static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {     // validate and proceed        if (subscriber == null) {            throw new IllegalArgumentException("observer can not be null");        }        if (observable.onSubscribe == null) {            throw new IllegalStateException("onSubscribe function can not be null.");            /*             * the subscribe function can also be overridden but generally that's not the appropriate approach             * so I won't mention that in the exception             */        }        // new Subscriber so onStart it        subscriber.onStart();        /*         * See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls         * to user code from within an Observer"         */        // if not already wrapped        if (!(subscriber instanceof SafeSubscriber)) {            // assign to `observer` so we return the protected version            subscriber = new SafeSubscriber<T>(subscriber);        }        // The code below is exactly the same an unsafeSubscribe but not used because it would         // add a significant depth to already huge call stacks.        try {            // allow the hook to intercept and/or decorate            hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);            return hook.onSubscribeReturn(subscriber);        } catch (Throwable e) {            // special handling for certain Throwable/Error/Exception types            Exceptions.throwIfFatal(e);            // if an unhandled error occurs executing the onSubscribe we will propagate it            try {                subscriber.onError(hook.onSubscribeError(e));            } catch (Throwable e2) {                Exceptions.throwIfFatal(e2);                // if this happens it means the onError itself failed (perhaps an invalid function implementation)                // so we are unable to propagate the error correctly and will just throw                RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);                // TODO could the hook be the cause of the error in the on error handling.                hook.onSubscribeError(r);                // TODO why aren't we throwing the hook's return value.                throw r;            }            return Subscriptions.unsubscribed();        }    }

其实在这写代码中,很多都是注释,下面我们来看下逻辑,
1:当我们传入observer2的时候,可以看到前面进行的一系列的判断。2:有一个onStart方法,而这个方法在rxJava只是一个空实现,所以我们在这里可以先不用管他。
3:把subscribe包装成了一个SafeSubscriber对象。
4:接下来的这句话,才是一切回调的开始,

hook.onSubscribeStart(observable,observable.onSubscribe).call(subscriber);

这里的OnSubscribe对象,是我们第一次调用from的时候保存的OnSubscribe对象,即我们自己创建的匿名的OnSubscribe
对象,而这里的入参,是我们第二次创建的observer2,当我们调用call方法的时候,即:

这里写图片描述

call方法被执行,开始循环遍历值(即上面提到的it),当it中有值的时候,会调用setProducer()方法,

这里写图片描述

它也只是简单的保存了一下值。
再来看看setProducer()方法,

这里写图片描述

传入了一个producer对象,当经过判断以后,会执行最下面的request方法,即刚才传入的IterableProducer类中的request方法,下面看下这个方法:

@Override        public void request(long n) {            if (get() == Long.MAX_VALUE) {                // already started with fast-path                return;            }               if(n==Long.MAX_VALUE&&compareAndSet(0,Long.MAX_VALUE)) {                fastpath();            } else             if(n>0&&BackpressureUtils.getAndAddRequest(this, n) == 0L) {                slowpath(n);            }        }        void slowpath(long n) {            // backpressure is requested            final Subscriber<? super T> o = this.o;            final Iterator<? extends T> it = this.it;            long r = n;            while (true) {                long numToEmit = r;                while (true) {                    if (o.isUnsubscribed()) {                        return;                    } else if (it.hasNext()) {                        if (--numToEmit >= 0) {                            o.onNext(it.next());                        } else                            break;                    } else if (!o.isUnsubscribed()) {                        o.onCompleted();                        return;                    } else {                        // is unsubscribed                        return;                    }                }                r = addAndGet(-r);                if (r == 0L) {                    // we're done emitting the number requested so                    // return                    return;                }            }        }        void fastpath() {            // fast-path without backpressure            final Subscriber<? super T> o = this.o;            final Iterator<? extends T> it = this.it;            while (true) {                if (o.isUnsubscribed()) {                    return;                } else if (it.hasNext()) {                    o.onNext(it.next());                } else if (!o.isUnsubscribed()) {                    o.onCompleted();                    return;                } else {                    // is unsubscribed                    return;                }            }        }    }

为什么要有一个producer接口对象呢?在上一章create的时候,我们是直接调用了observer中的onNext的方法,因为它发射的是一个对象,而from,我们更像是把传入的当成一个生产者,因为在iterable中不止一个对象。发射的是多个对象。

在这个方法中,看到有一个fastpath与一个slowpath方法(我这里为什么要写这两个方法,也不是很明白,如果知道的,可以在下面留言,告诉我一下哈,谢谢),在这两个方法里,都会去循环调用observer2中的onNext的方法,而observer2中的onNext的方法中又会去调用observer1中的方法,也就是我们自己写的方法,这样就完成了整个回调,而最后为什么会执行onComplete方法是因为当迭代结束的时候,会执行onComplete方法,

最后在subscribe方法中return了一个Subscription对象,是方便我们unSubscribe,可以防止内存溢出。

下面我们来总结一下,

**1. 我们创建了OnSubscribe对象,
2. 我们创建了observer1
3. 创建了observer2
4. subscribe方法调用OnSubscribe中的call方法
5. 创建一个producer对象
6. producer循环发射list中的数据,不断调用observer2中的onNext
7. observer2调用observer1中的onNext
8. 最后调用onComplete方法结束调用**

以上就是from的知识,感觉有点长,just方法的实现,请看下一节。

0 0
原创粉丝点击