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函数,代码上大家看下他们具体有什么差别。
- 我们看到传入的都是一个list,所以打印出来的内容都是一样的,但是默认最后都会执行onComplete这个方法,打印出OnComplete字符串。
其次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方法的实现,请看下一节。
- RxJava之just与from源码解读
- RxJava之just源码解读
- RxJava 源码解读分析 just
- RxJava 源码解读分析 from
- rxJava just和from区别
- RxJava 源码解读
- RxJava 操作符 just和from
- rxjava 操作符 just,from,scan,map
- RxJava 源码解读分析 Scheduler
- RxJava 源码解读分析 observeOn
- RxJava 源码解读分析 defer
- RxJava 源码解读分析 map
- RxJava 源码解读分析 flatMap
- RxJava新手入门之二 快捷发送事件just方法使用以及from拆分数组发送事件方法详解
- Android Rxjava之just方法的使用
- RX系列三 | RxJava | create | from | interval | just | range | filter
- RxJava 1.x from()和just()用法、区别和举例
- RxJava运用技巧-RxAndroid部分源码解读
- JS中继承方式
- 记录-关于String的字符串操作
- 20号笔试错题1
- tessract-ocr 训练步骤及对应命令
- iOS: property XXX cannot be found in forward class object XXX
- RxJava之just与from源码解读
- 20号笔试2
- 对象克隆
- 跨域的方式
- 面试总结
- 关于Logistic Regression & Softmax的文章和书摘总结
- 闭包
- 如何对网站进行优化提速
- Hexo框架博客编辑时图片的插入