Retrofit&RxJava

一、Retrofit详解

·Retrofit的官网地址为 :

http://square.github.io/retrofit/

Retrofit官网对于自身的介绍是 :

A type-safe HTTP client for Android and Java.

一种对于Android和Java类型安全的HTTP客户端

1、Retrofit的基本使用 :

从官网可以看到,Retrofit给我们示例了如何简单的请求网络以及得到结果对象,下面给大家看一个一般的get请求网络方式。

(1)首先定义一个接口对象


GitHubService接口中有一个getUser的方法,接收一个String类型的参数user用户名。该方法通过注解标明为Get请求方式。User对象就是一个JavaBean对象,里边有一些用户的参数信息。

(2)通过Retrofit得到GitHubService对象


这里指定了基本的url,配合着GET注解中的value值形成一个完整的请求路径。

(3)同步请求


由于是在主线程中请求网络,同步请求的方式需要new一个子线程来请求 :

(4)异步请求


通过上诉的代码我们就可以快速的完成一个GET方式的请求,而且Retrofit的源码中提供了有22种注解的方式来供我们请求网络以及配置请求方式。接下来我讲给你简略的介绍几种:

2、注解的使用和分析

(1)HTTP请求方式

在Retrofit请求Http的方式中一共提供了GET,POST,PUT,PATCH,DELETE,HEAD这几种标准的HTTP请求方法,我们可以看看GET和POST注解的源码 :

·GET


·POST


其他几个注解也都是类似,可以看到这些注解都是作用于方法上,并且是在运行时有效,JVM在运行时通过反射获得注解信息,也就是定义的时候的value值(默认是“”),一般用于动态设置具体的接口请求path,配合BaseUrl组成一个完整的Url,所以如何动态传递path,Retrofit也给我们提供了一个注解Path。@Path:所有在网址中的参数(URL的问号前面)

不过除了使用上诉的基本HTTP请求方式以外,Retrofit还给我们提供了一种HTTP注解的方式可以自己配置请求方式和path,可以看到下面的代码我使用了HTTP注解的方式同样也可以达到GET请求方式的效果 :

(2)请求参数的不同配置

我们都知道在请求的过程中我们是可以携带请求参数给服务器的,Get请求是直接拼接在Url后面,而Post请求是放在boby中。下面就开始介绍下Query,QueryMap,Boby,Filed,Part,Header一些注解的使用 :

·Query和QueryMap

Query和QueyMap是作用于请求Url上的参数表现形式,比如我们要请求一个GitHub上的某一个用户的关注用户,具体URl路径是 :

http://baseurl/users/{user}/following?Sort=id

那么就可以通过PATH和QUERY注解的方式来表达,具体代码如下,定义请求方法 :


具体请求代码如下 :


同样的如果请求需要带多个参数,那么可以使用QueryMap,比如 :


·Body

Body的使用主要用于POST请求,携带参数,使用跟一般请求网络框架没什么差别,比如我想在GitHub上创建一个用户,那么需要携带一个User对象过去,这时使用Post提交就非常方便了 :


具体请求代码 :


·Filed和FiledMap


Filed和FiledMap主要是与FormUrlEncoded注解配合,提交表单的键值对信息,作用于参数上,在运行时解析。比如我想以表单的方式提交修改用户名 :

具体代码调用 :


FieldMap就是需要携带多个键值对的时候通过map集合传递,Map如果是非String类型会调用其toString方法。

·Part和PartMap

Part和PartMap与注解Multipart配合使用,用于文件的上传,如果是单文件上传使用Part即可,如果是多文件上传使用PartMap;作用于参数上,并且在运行时解析。


具体代码调用 :


·Header,HeaderMap和Headers

Header和Headers用于添加请求头信息,不过需要注意的是,Header和HeaderMap,是作用于参数上,用于不确定的header值,而headers是作用于方法体上,用于添加固定的值。


二、RxJava的简介


在学习RxJava前首先需要了解ReactiveX,因为RxJava是ReactiveX的一种Java的实现形式。

·ReactiveX的官网地址为 :

http://reactivex.io/

ReactiveX官网对于自身的介绍是 :

An  API  for  asynchronous  programming  with  observable  streams.

一种在异步编程设计中使用的基于可观察的事件流接口。

实质上我们可以对其解读为三部分:

1、An API :首先它是个编程接口,不同语言提供不同实现。例如Java中的RxJava。

2、For asynchronous programming :在异步编程设计中使用。例如开启子线程处理耗时的网络请求。

3、With observable streams :基于可观察的事件流。例如观察者模式中观察者对被观察者的监听。

而ReactiveX结合了如下三部分内容 :

1、观察者模式,即定义对象间一种一对多的依赖关系,当一个对象改变状态时,则所有依赖它的对象都会被改变。

2、Iterator模式,即迭代流式编程模式,或者可以叫做迭代器模式。

3、函数式编程模式,即提供一系列的函数样式的方法供快速开发。

ReactiveX的模式图如下 :


三、RxJava的使用

1、RxJava的优势

在Android的SDK中,给开发者提供的用于异步操作的原生内容有AsyncTask和Handler。对于简单的异步请求来说,使用Android原生的AsyncTask和Handler即可满足需求,但是对于复杂的业务逻辑而言,依然使用AsyncTask和Handler会导致代码结构混轮,代码的可读性非常差。但是RxJava的异步操作是基于观察者模式实现的,在越来越复杂的业务逻辑中,RxJava依旧可以保持简洁。

2、RxJava的配置

首先,在Android Studio中配置Module的build.gradle,在这里我们使用的版本是1.2版本,并且导入RxAndroid,辅助RxJava完成线程调度 :


然后,RxJava基于观察者设计模式,其中的关键性三个步骤如下 :

(1)Observable被观察者

Observable被观察者创建的代码如下 :


在这里,要强调的是Observable被观察者是类类型,其中诸多方法,我们关注其构造函数与创建Observable对象的方法,查看如下图对应的视图结构 :


查看源码:




通过源码分析,可知Observable提供了create()方法来获取Observable实例对象。此外,除了基本的创建的方法,Observable还提供了便捷的创建Observable序列的两种方式,代码如下 :

·第一种,会将参数逐个发送


第二种,会将数组元素逐个转换完毕后逐个发送


其中Observable.just()方法会调用from()方法,查看源码可知 :


(2)Observer观察者

 Observer观察者创建的代码如下 :


Observer是接口,其中包含的方法有onCompleted()、onNext()、onError()。查看如下图所示Observer的视图结构 :


那么在RxJava中,Observer有其接口实现类对象Subscriber,它们的使用onNext()、onCompleted()、onError()方法是一样的,但是Subscriber对于Observer接口进行了拓展,在RxJava的subscribe过程中,Observer也是总会先被转换成一个Subscriber再使用,代码如下 :


其中,onStart()方法会在事件未发送前被调用,可以用于订阅关系建立前的准备工作,例如将数据清空或者重置,在Subscriber中默认是空实现,我们可以在该方法中调用自己的业务逻辑代码。在如下的视图结构中我们可以看到Subscriber的拓展内容,重点是add()、unsubscribe()方法以及名为subscription的Subscription队列。


(3)Subscribe订阅关系

Observable与observer形成订阅关系代码如下 :


那么我们以observable.subscribe(observer)为例在这里继续查看源码,查看subscribe()方法到底做了什么 :


Observer转换为Subscriber对象在这里得到印证。

在之后的内容中统一以Subscriber作为订阅观察者对象

继续深入,我们可以看到订阅关系中的关键步骤(仅核心代码):


在这里RxJavaHooks.onObservableStart(observable,observable.onSubscribe).call(subscriber)等价于OnSubscribe.call(subscriber),见下图 :


可以看到,subscriber()做了3件事 :

1.调用Subscriber.onStart()。该方法用于在订阅关系建立之前的准备。

2. 调用Observable中的OnSubscribe.call(Subscriber)。OnSubscribe是Observable的内部接口,而事件发送的逻辑在这里开始运行。从这也可以看到,在RxJava中当subscribe()方法执行的时候订阅关系确立,Observable开始发送事件。

3. 将传入的Subscriber作为Subscription返回。这是为了方便后续调用unsubscribe()。

四、RxJava的不完整回调


1、不完整回调的代码示例


 2、不完整回调的原理分析

在这里我们可以看到:

Action0无参数泛型无返回值类型,而Subscriber中的onCompleted()方法也没有参数泛型

Action1有1个参数泛型无返回值类型,onNextAction设置的参数泛型为String,而Subscriber中的onNext()方法参数泛型也是String(和文本中观察者对象中的OnNext方法对比)

Action1有1个参数泛型无返回值类型,onErrorAction设置的参数泛型为Throwable,而Subscriber中的onError()方法参数泛型也是Throwable

那么,我们来查看observable.subscribe(onNextAction)的源码,在这里,Action1可以被当成一个包装对象,将onNext()方法进行包装作为不完整的回调传入到observable.subscribe()中。


我们来看看Action1有何玄机,Action1的源码如下图所示 :


实质上,这种根据参数泛型的个数无返回值类型的包装在RxJava中有多种如下图所示的体现,例如Action0的参数个数为0,Action1的参数个数为1以此类推 :


五、RxJava的线程切换

1、Scheduler线程调度器

如果不指定线程,默认是在调用subscribe方法的线程上进行回调,那么如果子线程中调用subscribe方法,而想在主线程中进行UI更新,则会抛出异常。当然了RxJava已经帮我们考虑到了这一点,所以提供了Scheduler线程调度器帮助我们进行线程之间的切换。实质上,Scheduler线程调度器和RxJava的操作符有紧密关联,欲知后事,请继续往下看。

RxJava内置了如下所示几个的线程调度器 :

1、Schedulers.immediate():在当前线程中执行

2、Schedulers.newThread():启动新线程,在新线程中进行操作

3、Schedulers.io():I/O操作(读写文件、读写数据库、网络信息交互等)所使用的Scheduler。行为模式和newThread()差不多,区别在于io()的内部实现是用一个无数量上限的线程池,可以复用空闲的线程,因此多数情况下io()比newThread()更有效率。不要把计算工作放在io()中,可以避免创建不必要的线程。

4、Schedulers.computation():计算所使用的Scheduler。这个计算指的是CPU密集型计算,即不会被I/O等操作限制性能的操作,例如图形的计算。这个Scheduler使用的固定的线程池,大小为CPU核数。不要把I/O操作放在  ()中,否则I/O操作的等待时间会浪费CPU。

5、Schedulers.trampoline():会将任务按添加顺序依次放入当前线程中等待执行。线程一次只执行一个任务,其余任务排队等待,一个任务执行完成之后再开始下一个任务的执行。

此外RxJava还提供了用于测试的调度器Scheduler.test()及可自定义Scheduler—Schedulers.form()。

RxAndroid为我们提供了AndroidSchedulers.mainThread()进行主线程的回调

2、线程控制

调用Observable对象的subscribeOn()、observeOn()方法即可完成线程控制。

·subscribeOn():指定subscribe()所发生的线程,即Observable.OnSubscribe被激活是所处的线程。或者叫做事件产生的线程。

·observeOn():指定Subscriber所运行的线程。或者叫做事件消费的线程。 


六、操作符

 

一、操作符的概述

 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使数据处理简洁易懂。操作符实质上就是RxJava函数式编程模式的体现。

RxJava操作符的类型众多,详细解释下以下9种操作符 :


二、RxJava操作符详解

 1、创建操作符

 创建操作符的分类如下图所示:


(1)create操作符

create操作符在上边已经讲过,主要是用来实例化Observable对象的。

(2)from操作符

在这里以发送数组为例,from操作符的使用代码如下所示 :


首先,我们查看如下所示from操作符的结构图,可以看到它有多种实现方式,但是有一个共同点,都会返回一个Observable对象。


实质上,Observable将数组中的元素逐个进行发送,在发送过程中转换为Observable对象。进一步查看源码 :


可得知from操作符的作用 :将一个Iterable、一个Future、 或者一个数组,内部通过代理的方式转换成一个Observable。Future转换为OnSubscribe是通过OnSubscribeToObservableFuture进行的,Iterable转换通过OnSubscribeFromIterable进行。数组通过OnSubscribeFromArray转换。

(3)just操作符

使用代码如下所示 :





查看just操作符的结构图,结合源码得知,just操作符将单个参数发送的内容通过ScalarSynchronousObservable转换为一个新的Observable对象,而将多个参数发送的内容转换为一个数组,然后将数组通过from操作符进行发送。

(4)interval操作符

interval操作符使用代码如下所示 :



查看interval的结构图,其只能发送Long类型的数,实质上其作用为:创建一个按固定时间间隔发射整数序列的Observable,这个序列为一个无限递增的整数序列。需要注意的是:interval默认在computation调度器上执行。你也可以传递一个可选的Scheduler参数来指定调度器。

(5)range操作符

range操作符使用的代码如下所示 :


range操作符发射一个范围内的有序整数序列,并且我们可以指定范围的起始和长度


(6)repeat操作符

repeat操作符使用的代码如下所示 :


在这里需要强调一下,它不是创建一个Observable,而是重复发射原始Observable的数据序列,这个序列或者是无限的,或者通过repeat(n)指定重复次数。

2、变换操作符

在这里我介绍如下图所示7种变换操作符,变换操作符的作用是将源Observable发送的数据进行变换。


(1)map操作符

map操作符使用的代码如下所示 :


map操作符将源Observable发送的数据转换为一个新的Observable对象。在这里,Func1和Action的区别在于,Func1包装的是有返回值的方法。另外,和ActionX 一样,FuncX 也有多个,用于不同参数个数的方法。FuncX 和 ActionX 的区别在 FuncX 包装的是有返回值的方法。

(2)flatMap操作符

flatMap操作符使用的代码如下所示 :


源Observable通过flatMap操作符转换为包含源Observable发送的所有子条目的Observable集合,可见下图的示意图,然后从Observable集合中逐个取出转化为单个Observable对象进行发送。不同于map操作符的一点就是一对多的转化。


它的应用场景可以体现在源Observable发送的内容为一个复杂的数据集,例如一个Bean对象,而该外层Bean对象中一个成员变量为另一个内层Bean对象,我们想要拆解外层Bean对象获取内层Bean对象,就可以用flatMap操作符。注意:FlatMap对这些Observables发射的数据做的是合并(merge)操作,因此它们可能是交错的。

(3)concatMap操作符

concatMap操作符使用的代码如下所示 :


concatMap操作符类似于flatMap操作符,不同的一点是它按次序连接。

(4)cast操作符

cast操作符使用的代码如下所示 :


cast操作符将源Observable发送的数据都强制转换为一个指定的类型,然后再发射数据。需强调的一点是只能由父类对象转换为子类对象,否则会报错。

(5)flatMapIterable操作符

flatMapIterable操作符使用的代码如下所示 :


flatMapIterable相当于是flatMap的变体,直接在内部以Iterable接口将集合数据进行接收,示意图如下所示 :


(6)buffer操作符

 buffer操作符使用的代码如下所示 :


buffer操作符将原有Observable转换为一个新的Observable,这个新的Observable每次发送一组值,而不是一个个进行发送,我们可以定义这个新的Observable存放几个原有的Observable对象。


(7)groupBy操作符

groupBy操作符使用的代码如下所示 :


groupBy操作符,将原有的Observable对象转换为发送一组Observable集合的GroupedObservable对象,可以做分组操作,GroupedObservable将分组完毕的Observable对象可以继续发送。

注意:groupBy将原始Observable分解为一个发射多个GroupedObservable的Observable,一旦有订阅,每个GroupedObservable就开始缓存数据。因此,如果你忽略这些GroupedObservable中的任何一个,这个缓存可能形成一个潜在的内存泄漏。因此,如果你不想观察,也不想忽略GroupedObservable。你应该使用像ake(0)这样会丢弃自己的缓存的操作符。

3、过滤操作符

过滤操作符用于从Observable发射的数据中进行选择,在这里介绍如下图所示的8种。


(1)filter操作符

filter操作符使用的代码如下所示 :


filter默认不在任何特定的调度器上执行。

(2)elementAt操作符

elementAt操作符使用的代码如下所示 :


elementAt操作符获取原始Observable发射的数据序列指定索引位置的数据项,然后当做自己的唯一数据发射。对应示意图如下:


(3)distinct操作符

distinct操作符使用的代码如下所示 :


在这里需要强调一点:distinct操作符只允许还没有发射过的数据项通过。

(4)skip操作符

skip操作符使用的代码如下所示 :


skip操作符抑制Observable发射的前N项数据,只发送后N项数据


(5)take操作符


take操作符只发送前N项数据


(6)ignoreElements操作符


IgnoreElements操作符抑制原始Observable发射的所有数据,只允许它的终止通知(onError或onCompleted)进行发送。

(7)throttleFirst操作符


throttleFirst操作符会按照规定的时间,只发送第一个数据。

注:throttleFirst操作符默认在computation调度器上执行,但是你可以使用第三个参数指定其它的调度器。

(8)throttleWithTimeOut操作符


源Observable发射数据时,如果两次数据的发射间隔小于指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才进行发射。

4、组合操作符

组合操作符用于将多个Observable组合成一个单一的Observable,在这里我介绍如下图所示5种操作符 :


(1)startWith操作符

startWith操作符使用的代码如下所示


很简单,会在发送的数据序列前插入数据序列,并且会发送插入的数据序列。

(2)merge操作符

merge操作符使用的代码如下所示 :


如下图所示,merge操作符会将多个Observable对象进行合并。


需要注意的是:merge可能会让合并的Observable发射的数据交错。在这里我将firstObservable指定在IO线程中进行发送,secondObservable没有指定线程,两者合并然后发送数据时便会产生数据交错的现象。

(3)concat操作符

concat组合操作符使用的代码如下所示 :


concat操作符不同于merge操作符的区别就是:会将多个Observable对象合并到一个Observable对象中进行发送,严格按照顺序进行发送。如下图所示,直到第一个Observable发送完毕数据后,第二个Observable才会进行数据的发送。


(4)zip操作符

zip组合操作符使用的代码如下所示 :



zip操作符返回一个Obversable,它使用这个函数按顺序结合两个或多个Observables发射的数据项,然后它发射这个函数返回的结果。它按照严格的顺序进行数据发送。它只发射与发射数据项最少的那个Observable一样多的数据。

 (5)combineLastest操作符

combineLastest组合操作符使用的代码如下所示 :


当两个Observables中的任何一个发射了数据时,使用一个函数结合每个Observable发射的最近数据项,并且基于这个函数的结果发射数据。

5、辅助操作符

辅助操作符就是处理Observable的帮助动作,在这里介绍如下5种辅助操作符。


(1)delay操作符

delay操作符使用的代码如下所示 :


在这里我将延时时间设置为2秒,延迟指定的时间后发射源Observable中的数据。

(2)do操作符

do操作符使用的代码如下所示 :


do操作符,其下细分有很多内容,以doOnNext为例,其作用就是为源Observable对象发送数据后,当Subscriber接收到数据时,即当Subscriber的onNext方法被调用时,提供回调相应数据。

(3)subscribeOn操作符

(4)observeOn操作符

observeOn操作符使用的代码如下所示 :


subscribeOn操作符,指定subscribe()所发生的线程,即Observable.OnSubscribe被激活时的线程,或者叫做事件产生的线程。

observeOn操作符,指定Subscriber所运行的线程,或者叫做事件消费的线程。

在上边提到Schedulers可以使得RxJava实现线程切换,实质上就是借助于lift变换方法进行转换,subscribeOn发生在下图的通知过程,observeOn发生在下图中的发送过程。


(5)timeout操作符

timeout操作符使用的代码如下所示 :


需要强调的一点是,在这里timeout(long timeout, TimeUnit timeUnit, Observable other)是timeout其中的一种,它在超时的时候会将源Observable转换为备用的Observable对象进行发送。

6、错误操作符


(1)catch操作符

实质上在这里catch操作符细分有三种实现方案:onErrorReturn、onErrorResumeNext、onExceptionResumeNext。

·首先分析onErrorReturn的代码 :


onErrorReturn操作符,会在遇到错误时,停止源Observable的,并调用用户自定义的返回请求,实质上就是调用一次OnNext方法进行内容发送后,停止消息发送。

·然后分析onErrorResumeNext的代码 :


onErrorResumeNext操作符,会在源Observable遇到错误时,立即停止源Observable的数据发送,并取用新的Observable对象进行新的数据发送。

·最后,分析onExceptionResumeNext的代码 :


onExceptionResumeNext,会将错误发给Observer,而不会调用备用的Observable。

(2)retry操作符

retry操作符实现的代码如下所示 :


retry操作符不会将原始Observable的onError通知传递给观察者,它会重新订阅这个Observable。


7、布尔操作符

布尔操作符根据给定规则进行判断,是否符合规则然后返回布尔值。布尔操作符意义简单操作简便在这里介绍如下5种 :


(1)all操作符

all操作符实现的代码如下所示 :


all操作符,对源Observable发送的每一个数据根据给定的条件进行判断。如果全部符合条件,返回true,否则返回false。

(2)contains操作符

contains操作符实现的代码如下所示 :


contains操作符,对源Observable发送的数据是否包含定义的选项进行判断。如果包含返回true,否则返回false。

 (3)isEmpty操作符

isEmpty操作符实现的代码如下所示 :


isEmpty操作符,对源Observable发送的数据是否为空进行判断。如果源Observable发送的数据为空返回true,否则返回false。

 (4)exists操作符

exists操作符实现的代码如下所示 :


exists操作符,对源Observable发送的单独一个数据根据给定的条件进行判断。如果有一个数据符合条件,返回true,否则返回false。

(5)sequenceEqual操作符

sequenceEqual操作符实现的代码如下所示 :


 sequenceEqual操作符,对两个Observable进行判断,两个Observable相同时返回true,否则返回false。这里包含两个Observable的数据,发射顺序,终止状态是否相同。

8、条件操作符


(1)amb操作符

amb操作符实现的代码如下所示 :


如下图所示,首先发送通知给Amb的那个,不管发射的是一项数据还是一个onError或onCompleted通知。Amb将忽略和丢弃其它所有Observables的发射物。


(2)defaultlfEmpty操作符

amb操作符实现的代码如下所示 :


9、转换操作符

转换操作符可以将Observable转换为其它的对象或数据结构。在这里介绍如下所示三种转换操作符:


(1)toList操作符

toList操作符实现的代码如下所示:


通常,发射多项数据的Observable会为每一项数据调用onNext方法。你可以用toList操作符改变这个行为,让Observable将多项数据组合成一个List,然后调用一次onNext方法传递整个列表。

(2)toSortedList操作符

toSortedList操作符实现的代码如下所示:


不同于toList操作符的是,它会对产生的列表排序,默认是自然升序。

 (3)toMap操作符

toMap操作符实现的代码如下所示:


源Observable发送的数据作为键值对中的值,我们可以提供一个用于生成Map的Key的函数,然后不同的键存储源Observable发送的不同的值。toMap默认不在任何特定的调度器上执行。


七、RxJava1与RxJava2的区别

·Observable和Flowable

在RxJava1中backpressure被集成到了Observable中,官方也提供了很多方法让我们来处理backpressure问题。但是有一些特殊的场景根本无法用其来解决,最常见的例如UI事件。而不处理backpressure有可能导致MissingBackpressureException的出现。为了解决这个问题,在RxJava2里,引入了Flowable这个类:Observable不包含backpressure处理,而Flowable包含。

例如两个对象都以10毫秒一次派发数据,同时发生Integer.MAX_VALUE个数据:

·对于Observable

他会按照0,1,2,3,4...的顺序依次发送,而没有发送的数据将会存在内存中。如果在RxJava1中,内存数据超过128个时将会抛出MissingBackpressureException错误;而在RxJava2中并不会报错,数据会一直放在内存中,直到发生outOfMemoryError。

·对于Flowable

在创建的时候设定了FlowableEmitter.BackpressureMode.DROP,一开始他会输出0,1,2,3...127但之后会忽然跳跃到966,967,968...。中间的部分数据由于缓存不了,被抛弃掉了。

Single

和Observable,Flowable一样会发送数据,不同的是订阅后只能接受到一次 :

普通的Observable可以使用toSingle转换:observable.just(1).toSingle()

Completable

与Single类似,只能接受到完成(onComplete)和错误(onError)同样也可以由普通的Observable转换而来 :observable.just(1).toCompletab()

Base reactive interfaces

和Flowable的接口Publisher类似,Observable、Single、Completable也有类似的基类ObservableSource、SingleSource、CompletableSource。因此许多操作符接受的参数从以前的具体对象,变成了现在的接口,由于接收的都是接口,在使用其他遵循Reactive-Streams设计的第三方库的时候,就不需要把他自定义的Flowable转换成标准的Flowable了。

Subjects and Processors

io.reactivex.subjects.AsyncSubject,

io.reactivex.subjects.BehaviorSubject,

io.reactivex.subjects.PublishSubject,

io.reactivex.subjects.ReplaySubject,

io.reactivex.subjects.UnicastSubject,

在RxJava2中依然存在,但现在他们不支持backpressure。新出现的

io.reactivex.processors.AsyncSubject,

io.reactivex.processors.BehaviorSubject,

io.reactivex.processors.PublishSubject,

io.reactivex.processors.ReplaySubject,

io.reactivex.processors.UnicastSubject,

支持backpressure。

Functional interfaces

需要注意一点是,现在RxJava2的接口方法里加上了throws Exception,意味着在这些方法里调用一些会发生异常的方法不需要try-catch了。

Actions

另外大部分接口方法都按照Java8的接口方法名进行了相应的修改,比如Consumer接口原来叫Action1,而Action2改名成了BiConsumer,而Action3 - Action9被删掉了,大概是因为没人用。

Functions

跟Actions一样,基本就是名字的修改和不常用类的删除。

Subscriber

RxJava1里的Subscriber只是一个空接口,在RxJava2中Subscriber被赋予了更多的作用,有几个实现类可以供我们使用,例如 :


request()方法可以控制当前subScriber需要接收几个事件。而且,还可以调用subscriber.dispose()来断开对信号的监听。同时onCompleted方法改成了onComplete。意味着完成时调用这个方法,而不是完成后调用。由于Subscription被改掉了。如果需要类似以前CompositeSubscription的用法,可以使用 :


注意这里需要使用subscribeWith而不是subscribe,因为subscribe方法现在返回void。

Subscription

在RxJava1里,Subscription起到的是订阅桥梁的作用。在RxJava2中,由于Subscription本身和Reactive-Streams里的另外一个同名概念冲突。因此吧原本的Subscription改名成了Disposable。除了上边的subscribe(Subscriber)方法返回void,其他名为subscribe的方法都返回Disposable。

相应的

·CompositeSubscription改名成了CompositeDisposable

·SerialSubscription和MultipleAssignmentSubscription被合并到了SerialDisposable里set()方法会处理掉的值,而replace()方法不会。

·RefCountSubscription被移除了

Backpressure

在上边Observable and Flowable里已经说到了这个问题,在RxJava2中,Observable将不会处理backpressure,也就不会发生MissingBackpressureException问题,但内存依然会缓存多余的数据。而在使用Flowable时,如果配置Backpressure有问题,那么MissingBackpressureException依然存在。

Schedulers

RxJava2里依然包含了computation,io,newThread和trampoline这些默认线程调度。而immediate被移除了,因为他经常被人错误使用。同时Schedulers.test也被移除了。

Operator differences

操作符的改动不大,大部分是扩充了参数数量。或者是加入prefetch代表可以加入预置数据。

可以明显的看到,RxJava2最大的改动就是对于backpressure的处理,为此将原来的Observable拆分成了新的Observable和Flowable,同时其他相关部分也同时进行了拆分。除此之外,他还是我们最熟悉和喜爱的RxJava。

更多区别:

https://blog.csdn.net/jeasonlzy/article/details/74269443

Retrofit1.0和2.0的区别与改进 :

https://www.jianshu.com/p/18cec5107ddc

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3460.html

构建者模式(Builder模式):

https://www.jianshu.com/p/0adc46f457be

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 一、RxJava操作符概述 RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易...
    测天测地测空气阅读 626评论 0 1
  • 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy阅读 5,460评论 7 62
  • 转一篇文章 原地址:http://gank.io/post/560e15be2dca930e00da1083 前言...
    jack_hong阅读 910评论 0 2
  • 前言我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard...
    占导zqq阅读 9,159评论 6 151
  • 每日推荐: 每日一歌――刘惜君《光》 每日一诗――宋·王安石《元日》 爆竹声中一岁除, 春风送暖入屠苏。 千门万户...
    萨拉芯雪阅读 313评论 0 1