RxJava简单总结

##.简介

    RxJava是是一个基于事件流处理来实现异步操作的库。对于需要切换线程来异步处理的场景,能够简化代码编写,提高代码可读性。官网地址: ReactiveX

一、使用流程概括和示例

1.它是按照观察者模式来设计的

    被观察者负责生产事件,观察者负责处理事件,一旦观察者 订阅了 被观察者,就会触发被观察者发送事件流。
    这里的“事件”是一个抽象概念,它的载体是一个数据结构(例如String/Object/自定义对象等),传递的实际上是数据,只是在观察者模式中它们的角色是“事件”。事件流对应的,是要传递的数据流。

2.使用流程和示例

大致可分为3步:
1)创建被观察者,编写事件生产和发送逻辑;
    通过事件发射器 FlowableEmitter的onNext()/onComplete()/onError()等来传递事件。
2)创建观察者,编写事件处理逻辑;
    通过自己的 onNext()/onComplete()/onError()等来接受事件并处理。
    注意:上游事件发送正常结束时 onComplete()被调用, onError()在出错时被调用,二者出现时都意味着事件流处理结束,但二者只会有一个被调用到。
3)观察者 订阅 被观察者,触发 被观察者生产和发送时间,然后观察者接收事件并处理。
代码示例和注释讲解:
/**
* 1.创建被观察者
* 有多种创建方式,这是其中较常见一种,通过Create()方法创建
* 第二个参数是背压策略
*/
Flowable<String> flowable = Flowable.create(new FlowableOnSubscribe<String>() {
    /**
     * 被订阅后,会触发调用该方法
     * @param emitter   事件发射器,可通过它将事件传递给观察者
     * @throws Throwable
     */
    @Override
    public void subscribe(@NonNull FlowableEmitter<String> emitter) throws Throwable {
        //通过onNext()方法来传递事件(数据)
        emitter.onNext("aaa");
        emitter.onNext("bbb");
        emitter.onNext("ccc”);
        //调用onComplete(),意味着事件流发送已结束
        //后面再调用onNext()也不会再将事件发送出去
        emitter.onComplete();
    }
}, BackpressureStrategy.ERROR);

/**
* 2.创建观察者
*/
FlowableSubscriber<String> flowableSubscriber = new FlowableSubscriber<String>() {
    /**
     * 一旦订阅,会首先调用该方法
     * 传入的参数s是Subscription类型,对应的是"订阅"这个抽象概念
     * 通过调用Subscription.cancel()可以取消订阅,停止事件流发送和接收
     * @param s
     */
    @Override
    public void onSubscribe(@NonNull Subscription s) {

    }

    /**
     * 通过该方法将数据传递过来
     * @param s
     */
    @Override
    public void onNext(String s) {
        //.....处理数据.....
    }

    /**
     * 当出错时,该方法会被调用,事件流传递会结束掉。
     * onError()和onComplete()只会有一个被调用到。
     * @param t
     */
    @Override
    public void onError(Throwable t) {

    }

    /**
     * 该方法被调用,意味着事件流传递已结束
     * onError()和onComplete()只会有一个被调用到。
     */
    @Override
    public void onComplete() {

    }
};

/**
* 3.订阅
* 订阅后,首先会触发观察者执行onSubscribe()方法
* 然后会触发被观察者执行FlowableOnSubscribe.subscribe()内的逻辑,
*      观察者可在此方法中写生产事件和发射的逻辑,最终事件会在观察者的回调方法中被处理
*/
flowable.subscribe(flowableSubscriber);
习惯上会把以上步骤串在一起链式调用,这样写起来、读起来都更简便:
/**
* 习惯上会把以上步骤串在一起写,这些写起来、读起来都更简便
*/
Flowable.create(new FlowableOnSubscribe<String>() {
    //被订阅后,会触发调用该方法
    @Override
    public void subscribe(@NonNull FlowableEmitter<String> emitter) throws Throwable {
        //通过onNext()方法来传递事件(数据)
        emitter.onNext("aaa");
        emitter.onNext("bbb");
        emitter.onNext("ccc");
        //调用onComplete(),意味着事件流发送已结束
        //后面再调用onNext()也不会再将事件发送出去
        emitter.onComplete();
    }
}, BackpressureStrategy.ERROR)
        //设置被观察者生产和发送事件在IO线程执行
        .subscribeOn(Schedulers.io())
        //设置观察者处理事件在主线程执行
        .observeOn(AndroidSchedulers.mainThread())
        //订阅
        .subscribe(new FlowableSubscriber<String>() {
            @Override
            public void onSubscribe(@NonNull Subscription s) {
                //一旦订阅,会首先调用该方法
            }

            @Override
            public void onNext(String s) {
                //.....处理数据.....
            }

            @Override
            public void onError(Throwable t) {

            }

            @Override
            public void onComplete() {

            }
        });

二.异步处理相关

    RxJava中既可以配置被观察者生产/发送事件执行的线程,也可以配置观察者处理事件的线程,因此可以支持实现异步操作。

1.同步处理

    当不做任何线程调度配置时,默认二者都会在当前线程中执行,此时被观察者、观察者是同步执行的,发送一个事件、处理一个事件,然后继续进行下一轮发送和处理。

2.异步处理    

    当配置二者不在同一线程执行时,事件的发送和处理是异步的,被观察者将事件发送到对应的“事件缓冲区”,然后观察者从事件缓冲区取事件来处理。

3.背压策略

    异步处理时,有可能观察者处理事件较慢,而被观察者发送事件较快,则事件不停在 “事件缓冲区”堆积。 “事件缓冲区” 默认最多缓冲128个事件,一旦超出就会报错。所以需要一种策略来处理这种情况,缓解上游过快的事件流带来的压力,所以叫“背压策略”。
背压策略是针对缓冲区的策略,除了采用背压策略外,针对该问题,也可以通过其它方案解决:控制上游发送事件速度、或者让下游放弃处理部分事件。)
背压策略有:
3.1 BackpressureStrategy.ERROR:
    默认使用的背压策略,缓存量超出128个就触发onError(),传递异常 MissingBackpressureException
3.2 BackpressureStrategy.MISSING:
    跟 BackpressureStrategy.ERROR类似,onError()传递的信息中多了句提示内容。
3.3  BackpressureStrategy.BUFFER:
    将缓冲区设置为无限大,此时倒是不会报错了,但是事件如果一直在缓冲区累积下去,容易出现OOM问题。
3.4  BackpressureStrategy.DROP:
    缓存超过128个事件时,新发送的事件会被丢弃掉。
3.5  BackpressureStrategy.LATEST
    缓存超过128个事件时,会额外保存一个事件,只会额外保存最新发送的这个事件。

4.被观察者、观察者执行线程的配置

4.1配置方法

    通过subscribeOn()方法指定被观察者生产事件的线程,可指定多次,则只有第一次指定有效。
    通过 observeO()指定观察者处理事件的线程,可指定多次,每次指定均有效,每指定一次,就会切换一次线程。
    (RxJava是通过内部的 Schedulers调度器来实现线程切换的。)
示例:
        //设置被观察者生产和发送事件在IO线程执行
flowable.subscribeOn(Schedulers.io())
        //设置观察者处理事件在Android主线程执行
        .observeOn(AndroidSchedulers.mainThread());

4.2 RxJava内置线程类型

RxJava中内置了多种用于调度的线程类型。 RxJava使用线程池来维护这些线程,所以又较高调度效率。
类型
含义
应用场景
Schedulers.immediate()
当前线程 = 不指定线程
默认
AndroidSchedulers.mainThread()
Android主线程
操作UI
Schedulers.newThread()
常规新线程
耗时等操作
Schedulers.io()
io操作线程
网络请求、读写文件等io密集型操作
CPU计算操作线程
大量计算操作

三、被观察者类型

类型
描述
Observable<T>
能够发射0或n个数据,并以成功或错误事件终止。
Flowable<T>
能够发射0或n个数据,并以成功或错误事件终止。 支持Backpressure背压策略(事件缓冲区应对事件堆积过多时的策略)。
Single<T>
只发射单个数据或错误事件。
Completable
它从来不发射数据,只处理 onComplete 和 onError 事件。可以看成是Rx的Runnable。
Maybe<T>
能够发射0或者1个数据,要么成功,要么失败。有点类似于Optional

四、各种操作符

1.创建操作符:用于创建被观察者和事件

2.变换操作符:对于事件用指定函数处理后,将结果作为事件继续发送到下游

类型
作用
map()
1个源事件变换出一个结果事件,后继发送顺序不变
FlatMap()
源事件与结果事件对应关系随意,后继发送顺序随机
ConcatMap()
源事件与结果事件对应关系随意,后继发送顺序按照与源事件关系来排列
Buffer()
设置一个数量和步长,每轮从被观察者发送的事件集合中取指定数量发送到下游,下一轮按照步长移动后,依旧发送指定数量,不断重复此步骤知道全部发送完。
示例:
/**
* map示例
*/
flowable.map(new Function<String, Character>() {
    @Override
    public Character apply(String s) throws Throwable {
        //此处将事件类型String处理成Character,发送到下游
        return s.charAt(0);
    }
});

3.条件判断、过滤操作符:用于根据判断条件筛选出/过滤掉部分事件

4.组合 / 合并操作符:用于合并多个被观察者事件序列

5.其它操作符

类型
作用
delay()
延迟指定时间发送事件
doOnEach()
doOnNext()
doAfterNext()
doOnError()
每当对应类型时间发生前/后,都会执行执行方法
retry()
retryWhen()
出错时重试
repeat()
repeatWhen()
不断重复发送
(声明:部分图片来自网络,侵删!)

猜你喜欢

转载自blog.csdn.net/u013914309/article/details/125212341