RxAndroid 入门笔记

来源:互联网 发布:java项目架构文档 编辑:程序博客网 时间:2024/05/17 01:41

参考链接:
http://gank.io/post/560e15be2dca930e00da1083#toc_10
https://mcxiaoke.gitbooks.io/rxdocs/content/Observables.html
http://blog.chengyunfeng.com/?p=948
http://www.apkbus.com/blog-705730-62567.html

要了解RxAndroid,必须先要了解RxJava,应为RxAndroid是RxJava的一个重要的部分。

RxJava介绍

RxJava尽力做到非常轻巧。它仅关注Observable的抽象和与之相关的高层函数,实现为一个单独的JAR文件。

RxJava的github地址:https://github.com/ReactiveX/RxJava
RxAndroid的github地址:https://github.com/ReactiveX/RxAndroid

在RxJava中,一个实现了Observer接口的对象可以订阅(subscribe)一个Observable 类的实例。订阅者(subscriber)对Observable发射(emit)的任何数据或数据序列作出响应。这种模式简化了并发操作,因为它不需要阻塞等待Observable发射数据,而是创建了一个处于待命状态的观察者哨兵,哨兵在未来某个时刻响应Observable的通知。

Observable

observable(可观察者,被观察者),它决定什么时候触发事件以及触发怎样的事件。RxJava使用create()方法创建一个observable,并为它定义事件触发规则。

Observer

observer(观察者),它决定事件触发的时候将有怎样的行为。
回调方法(onNext,onComplete,onError)
onNext:
observable调用这个方法发射数据,方法的参数就是observable发射的数据,这个方法可能会被调用多次,取决于你的实现。
onComplete:
正常终止,如果没有遇到错误,observable在最后一次调用onNext之后调用此方法。
onError:
当observable遇到错误或无法返回期望的数据时会调用这个方法,这个调用会终止Observable,后续不会再调用onNext和onComplete,onError方法的参数是抛出的异常。

Subscriber

Subscriber 是 Observer 的一个实现。

Subscribe

订阅,将观察者和被观察者连接起来的方法。

关系图
这里写图片描述

操作符

  • 用于创建Observable的操作符

Create — 通过调用观察者的方法从头创建一个Observable
Defer — 在观察者订阅之前不创建这个Observable,为每一个观察者创建一个新的Observable
Empty/Never/Throw — 创建行为受限的特殊Observable
From — 将其它的对象或数据结构转换为Observable
Interval — 创建一个定时发射整数序列的Observable
Just — 将对象或者对象集合转换为一个会发射这些对象的Observable
Range — 创建发射指定范围的整数序列的Observable
Repeat — 创建重复发射特定的数据或数据序列的Observable
Start — 创建发射一个函数的返回值的Observable
Timer — 创建在一个指定的延迟之后发射单个数据的Observable

  • 变换操作

这些操作符可用于对Observable发射的数据进行变换,详细解释可以看每个操作符的文档

Buffer — 缓存,可以简单的理解为缓存,它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个
FlatMap — 扁平映射,将Observable发射的数据变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable,可以认为是一个将嵌套的数据结构展开的过程。
GroupBy — 分组,将原来的Observable分拆为Observable集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据
Map — 映射,通过对序列的每一项都应用一个函数变换Observable发射的数据,实质是对序列中的每一项执行一个函数,函数的参数就是这个数据项
Scan — 扫描,对Observable发射的每一项数据应用一个函数,然后按顺序依次发射这些值
Window — 窗口,定期将来自Observable的数据分拆成一些Observable窗口,然后发射这些窗口,而不是每次发射一项。类似于Buffer,但Buffer发射的是数据,Window发射的是Observable,每一个Observable发射原始Observable的数据的一个子集

  • 过滤操作

这些操作符用于从Observable发射的数据中进行选择

Debounce — 只有在空闲了一段时间后才发射数据,通俗的说,就是如果一段时间没有操作,就执行一次操作
Distinct — 去重,过滤掉重复数据项
ElementAt — 取值,取特定位置的数据项
Filter — 过滤,过滤掉没有通过谓词测试的数据项,只发射通过测试的
First — 首项,只发射满足条件的第一条数据
IgnoreElements — 忽略所有的数据,只保留终止通知(onError或onCompleted)
Last — 末项,只发射最后一条数据
Sample — 取样,定期发射最新的数据,等于是数据抽样,有的实现里叫ThrottleFirst
Skip — 跳过前面的若干项数据
SkipLast — 跳过后面的若干项数据
Take — 只保留前面的若干项数据
TakeLast — 只保留后面的若干项数据

  • 组合操作

组合操作符用于将多个Observable组合成一个单一的Observable

And/Then/When — 通过模式(And条件)和计划(Then次序)组合两个或多个Observable发射的数据集
CombineLatest — 当两个Observables中的任何一个发射了一个数据时,通过一个指定的函数组合每个Observable发射的最新数据(一共两个数据),然后发射这个函数的结果
Join — 无论何时,如果一个Observable发射了一个数据项,只要在另一个Observable发射的数据项定义的时间窗口内,就将两个Observable发射的数据合并发射
Merge — 将两个Observable发射的数据组合并成一个
StartWith — 在发射原来的Observable的数据序列之前,先发射一个指定的数据序列或数据项
Switch — 将一个发射Observable序列的Observable转换为这样一个Observable:它逐个发射那些Observable最近发射的数据
Zip — 打包,使用一个指定的函数将多个Observable发射的数据组合在一起,然后将这个函数的结果作为单项数据发射

  • 错误处理

这些操作符用于从错误通知中恢复

Catch — 捕获,继续序列操作,将错误替换为正常的数据,从onError通知中恢复
Retry — 重试,如果Observable发射了一个错误通知,重新订阅它,期待它正常终止

  • 辅助操作

一组用于处理Observable的操作符

Delay — 延迟一段时间发射结果数据
Do — 注册一个动作占用一些Observable的生命周期事件,相当于Mock某个操作
Materialize/Dematerialize — 将发射的数据和通知都当做数据发射,或者反过来
ObserveOn — 指定观察者观察Observable的调度程序(工作线程)
Serialize — 强制Observable按次序发射数据并且功能是有效的
Subscribe — 收到Observable发射的数据和通知后执行的操作
SubscribeOn — 指定Observable应该在哪个调度程序上执行
TimeInterval — 将一个Observable转换为发射两个数据之间所耗费时间的Observable
Timeout — 添加超时机制,如果过了指定的一段时间没有发射数据,就发射一个错误通知
Timestamp — 给Observable发射的每个数据项添加一个时间戳
Using — 创建一个只在Observable的生命周期内存在的一次性资源

  • 条件和布尔操作

这些操作符可用于单个或多个数据项,也可用于Observable

All — 判断Observable发射的所有的数据项是否都满足某个条件
Amb — 给定多个Observable,只让第一个发射数据的Observable发射全部数据
Contains — 判断Observable是否会发射一个指定的数据项
DefaultIfEmpty — 发射来自原始Observable的数据,如果原始Observable没有发射数据,就发射一个默认数据
SequenceEqual — 判断两个Observable是否按相同的数据序列
SkipUntil — 丢弃原始Observable发射的数据,直到第二个Observable发射了一个数据,然后发射原始Observable的剩余数据
SkipWhile — 丢弃原始Observable发射的数据,直到一个特定的条件为假,然后发射原始Observable剩余的数据
TakeUntil — 发射来自原始Observable的数据,直到第二个Observable发射了一个数据或一个通知
TakeWhile — 发射原始Observable的数据,直到一个特定的条件为真,然后跳过剩余的数据

  • 算术和聚合操作

这些操作符可用于整个数据序列

Average — 计算Observable发射的数据序列的平均值,然后发射这个结果
Concat — 不交错的连接多个Observable的数据
Count — 计算Observable发射的数据个数,然后发射这个结果
Max — 计算并发射数据序列的最大值
Min — 计算并发射数据序列的最小值
Reduce — 按顺序对数据序列的每一个应用某个函数,然后返回这个值
Sum — 计算并发射数据序列的和

  • 连接操作

一些有精确可控的订阅行为的特殊Observable

Connect — 指示一个可连接的Observable开始发射数据给订阅者
Publish — 将一个普通的Observable转换为可连接的
RefCount — 使一个可连接的Observable表现得像一个普通的Observable
Replay — 确保所有的观察者收到同样的数据序列,即使他们在Observable开始发射数据之后才订阅

  • 转换操作

To — 将Observable转换为其它的对象或数据结构
Blocking 阻塞Observable的操作符

还有一些其他的操作符:

Convert 转换操作 - ToFuture/ToList/ToIterable/ToMap/toMultiMap
Blocking 阻塞操作 - ForEach/First/Last/MostRecent/Next/Single/Latest
String 字符串操作 - ByLine/Decode/Encode/From/Join/Split/StringConcat
Async 异步操作 - Start/ToAsync/StartFuture/FromAction/FromCallable/RunAsync

Scheduler

RxJava的调度器(Schedulers)为实际生产提供了5中解决方案,如果需要大量IO操作,可以选择Schedulers.io()调度器,如果需要进行密集计算,可以选择Schedulers.computation(),如果只是想开一个线程做些事,可以选择Schedulers.newThread(),借助于RxAndroid,我们还可以使用AndroidSchedulers.mainThread()这个调度器将线程切换回主线程,选择了调度器后,使用一些方法可以将线程切换至调度器对应的线程中。

subscribeOn()和observeOn()

  • observeOn() 指定的是它之后的操作所在的线程。因此如果有多次切换线程的需求,只要在每个想要切换线程的位置调用一次 observeOn() 即可。
    原理图:
    这里写图片描述
  • subscribeOn() 的线程切换发生在 OnSubscribe 中,即在它通知上一级 OnSubscribe 时,这时事件还没有开始发送,因此 subscribeOn() 的线程控制可以从事件发出的开端就造成影响。
    原理图:
    这里写图片描述
Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定    .subscribeOn(Schedulers.io())    .observeOn(Schedulers.newThread())    .map(mapOperator) // 新线程,由 observeOn() 指定    .observeOn(Schedulers.io())    .map(mapOperator2) // IO 线程,由 observeOn() 指定    .observeOn(AndroidSchedulers.mainThread)     .subscribe(subscriber);  // Android 主线程,由 observeOn() 指定

不同于 observeOn() , subscribeOn() 的位置放在哪里都可以,但它是只能调用一次的。

当observeOn()和subscribeOn()同时存在时,数据源和操作流程会先处于subscribeOn()所在的线程,直到调用了observeOn()后,线程会切换至observeOn()所在的线程。

如果同时存在多个observeOn()和多个subscribeOn()会怎么样?多个observeOn()好理解,反正什么时候调用到了observeOn(),什么时候就切换线程。而多个subscribeOn()则不同,它们不会被覆盖,只有第一个subscribeOn()线程有效。

总结

create() , just() , from() 等 —-> 事件产生
map() , flapMap() , scan() , filter() 等 —-> 事件加工
subscribe() —-> 事件消费

事件产生:默认运行在当前线程,可以由 subscribeOn() 自定义线程
事件加工:默认跟事件产生的线程保持一致, 可以由 observeOn() 自定义线程
事件消费:默认运行在当前线程,可以有observeOn() 自定义

subscribeOn 用来指定 Observable.create 中的代码在那个 Scheduler 中执行。即使你没有调用 create 函数,但是内部也有一个 create 实现。
observeOn 只影响调用该函数以后的操作函数。你可以认为 observeOn 只是拦截了数据流并且对后续的操作有作用。

doOnSubscribe()

与 Subscriber.onStart() 相对应的,有一个方法 Observable.doOnSubscribe() 。它和 Subscriber.onStart() 同样是在 subscribe() 调用后而且在事件发送前执行,但区别在于它可以指定线程。默认情况下, doOnSubscribe() 执行在 subscribe() 发生的线程;而如果在 doOnSubscribe() 之后有 subscribeOn() 的话,它将执行在离它最近的 subscribeOn() 所指定的线程。

RxJava中ActionX与FuncX的区别

RxJava有一系列的(Func+数字)的接口和一系列(Action+数字)接口,这些接口中都只有一个call方法,其中(Func+数字)接口的call方法都有返回值,而(Action+数字)接口的call方法都没有返回值,后面的那个数字表示call方法接受几个泛型类型的参数。Func1和Action1的源码:

/** * Represents a function with one argument. */public interface Func1<T, R> extends Function {    R call(T t);}/** * A one-argument action. */public interface Action1<T> extends Action {    void call(T t);}

ActionX用在.subscribe()中的,传入的个数和位置决定用处。ActionX的返回值都为void。
Action1 和 Action0。 Action0 是 RxJava 的一个接口,它只有一个方法 call(),这个方法是无参无返回值的;由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。这样其实也可以看做将 onCompleted() 方法作为参数传进了subscribe(),相当于其他某些语言中的『闭包』。 Action1 也是一个接口,它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;与 Action0 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,因此 Action1可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。事实上,虽然 Action0 和 Action1在 API 中使用最广泛,但 RxJava 是提供了多个 ActionX 形式的接口 (例如 Action2, Action3) 的,它们可以被用以包装不同的无返回值的方法。

FuncX常用在map、flatMap中,将传过来的数值类型转化为另一种数值类型,“FuncX”中的“X”代表着多少个参数。
Func1 的类。它和 Action1 非常相似,也是 RxJava 的一个接口,用于包装含有一个参数的方法。 Func1 和Action 的区别在于, Func1 包装的是有返回值的方法。另外,和 ActionX 一样, FuncX 也有多个,用于不同参数个数的方法。FuncX和 ActionX 的区别在 FuncX 包装的是有返回值的方法。

0 0
原创粉丝点击