RxJava入门到进阶全攻略

一、RxJava基本使用

import android.util.Log;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

/**
 * RxJava2基础使用(分步骤创建使用和链式调用)
 *
 * 步骤1:创建被观察者 (Observable)& 生产事件
 * 步骤2:创建观察者 (Observer)并定义响应事件的行为;发生的事件类型包括:Next事件、Complete事件 & Error事件。
 * 步骤3:通过订阅(Subscribe)连接观察者和被观察者
 *
 * Rxjava2中的5种观察者模式:
 * Observable   --->     Observer 不支持背压
 * Flowable     --->    Subscriber(FlowableSubscriber继承自Subscriber) 支持背压
 * Single       --->    SingleObserver (订阅后只能接受到1次)
 * Completable  --->    CompletableObserver (订阅后只能接受 Complete 和 onError事件)
 * Maybe        --->    MaybeObserver
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/7 10:31
 */
public class RxJava1 {
    private static final String TAG = RxJava1.class.getSimpleName();
    // 被观察者
    private Observable<Integer> observable;
    private Flowable<Integer> flowable;
    // 观察者
    private Observer<Integer> observer;
    private Subscriber<Integer> subscriber;

    /**
     * 分布实现
     * 1.创建被观察者 Observable 对象,生产事件
     */
    public void createObservable() {
        observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                // 2. 在复写的subscribe()里定义需要发送的事件
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        });
        // 扩展:RxJava 提供了其他方法用于 创建被观察者对象Observable
        // 方法1:just(T...):直接将传入的参数依次发送出来
        Observable<String> observable1 = Observable.just("A", "B", "C");
        // 将会依次调用:
        // onNext("A");
        // onNext("B");
        // onNext("C");
        // onCompleted();

        // 方法2:fromArray(),fromCallable(),fromFuture(),fromIterable(),fromPublisher() :
        // 将传入的数组 / Iterable 拆分成具体对象后,依次发送出来
        // 在rxjava1中是form()函数,rxjava2中拆分出来了
        String[] words = {"A", "B", "C"};
        Observable<String> observable2 = Observable.fromArray(words);
        // 将会依次调用:
        // onNext("A");
        // onNext("B");
        // onNext("C");
        // onCompleted();

        //
        flowable = new Flowable<Integer>() {
            @Override
            protected void subscribeActual(Subscriber<? super Integer> s) {

            }
        };
    }

    /**
     * 分布实现
     * 2.创建观察者 Observer 对象
     *
     * 方式1:采用Observer 接口
     * 方式2:采用Subscriber 抽象类
     * 方式3:....
     * ......
     */
    public void createObserver(){
        // Next 普通事件;向观察者发送需要响应事件的信号
        // 注:被观察者可以发送无线个Next事件;观察者可接受无限个Next事件

        // complete 事件队列完结事件(Rxjava把所有事件当做队列处理);标志被观察者不再发送普通事件(Next);
        // 注:被观察者可以不发送Complete事件;被观察者发送完complete事件后可继续发送其它事件,但观察者收到complete后不再接受任何事件

        // Error 异常事件;标志事件处理出现异常,此时队列自动终止,不再有事件发出
        // 注:被观察者可以不发送Error事件;被观察者发送完Error事件后可继续发送其它事件,但观察者收到Error后不再接受任何事件

        // 注意:在一个正确的事件序列中,Error和Complete只能存在一个,二者互斥

        // 方式1:采用Observer 接口
        observer = new Observer<>() {
            // 观察者接收事件前,默认最先调用复写 onSubscribe():适合做初始化工作
            @Override
            public void onSubscribe(Disposable d) {
                // 传入的参数Disposable作用 类似于 Subsciption
                // 即相当于订阅关系的开关,可切断观察者和被观察者的订阅关系
                // 注:调用dispose()后,观察者无法接收事件,但被观察者还是会继续发送事件
                Log.d(TAG, "开始采用subscribe连接");
            }
            // 当被观察者生产Next事件,观察者接收到时,会调用该方法响应
            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "对Next事件作出响应" + integer);
            }
            // 当被观察者生产Error事件& 观察者接收到时,会调用该复写方法 进行响应
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }
            // 当被观察者生产Complete事件& 观察者接收到时,会调用该复写方法 进行响应
            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        };

        // 方式2:采用Subscriber 抽象类
        // 说明:Subscriber类 = RxJava 内置的一个实现了 Observer 的抽象类,对 Observer 接口进行了扩展
        subscriber = new Subscriber<>() {
            @Override
            public void onSubscribe(Subscription s) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "对Next事件作出响应" + integer);
            }

            @Override
            public void onError(Throwable t) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        };
    }

    /**
     * 分布实现
     * 3.通过订阅(Subscribe)连接观察者和被观察者
     * Observable---订阅-->Observer
     * Flowable---订阅-->Subscriber
     *
     */
    public void createSubscribe(){
        observable.subscribe(observer);
        flowable.subscribe(subscriber);
    }

    /**
     *  切断观察者 与 被观察者 之间的连接
     *  Disposable.dispose()
     */
    private void dispose(){
        // 主要在观察者 Observer中 实现
        Observer<Integer> observer = new Observer<Integer>() {
            // 1. 定义Disposable类变量
            private Disposable mDisposable;

            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
                // 2. 对Disposable类变量赋值
                mDisposable = d;
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "对Next事件"+ value +"作出响应"  );
                if (value == 2) {
                    // 设置在接收到第二个事件后切断观察者和被观察者的连接
                    mDisposable.dispose();
                    Log.d(TAG, "已经切断了连接:" + mDisposable.isDisposed());
                }
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        };
    }

    /**
     * 基于事件流的链式调用方式
     */
    private void rxjavaCallChaining(){
        // RxJava的流式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
            // 1. 创建被观察者 & 生产事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            // 2. 通过通过订阅(subscribe)连接观察者和被观察者
            // 3. 创建观察者 & 定义响应事件的行为
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }
            // 默认最先调用复写的 onSubscribe()
            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "对Next事件"+ value +"作出响应"  );
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        });
    }
}

二、RxJava2相对RxJava1更新了哪些东西

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

/**
 * RxJava2对比RxJava1更新了哪些东西
 *
 * 1.增加了Flowable支持背压
 * 背压策略(BackpressureStrategy,一个enum)如下(注意:异步缓存池中的数据默认的最大值为128):
 *
 * MISSING:不支持背压
 * ERROR:放入Flowable异步缓存池超过123,会抛出MissingBackpressureException,并给出友好提示,说明缓存区队列已经满了
 * BUFFER:超过128,会抛出MissingBackpressureException异常
 * DROP:超过128,会将超出无法存入的事件给丢弃掉
 * LATEST:此时如果Flowable继续发送数据的话,缓存池会将之后的数据都给丢弃掉,但是还会缓存发送的事件中最后一次发送的数据
 *
 * 2.简化订阅方法
 *  Action
 *  Consumer(接受1个参数)
 *  BiConsumer(接受2个参数)
 *  Consumer<Object[]> (接收多个参数)
 *
 *  Function (用于变换对象)
 *  BiFunction
 *  Function3 - Function9
 *  Function<Object[], R>
 *
 *  3.RxJava2的接口方法都允许抛出异常, 这意味着,在这些方法里调用会发生异常的方法不需要try-catch
 *  RxJava 2.0 不再支持 null 值,如果传入一个null会抛出 NullPointerException
 *
 *  4.操作符的改变,后面单独练习
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/7 15:56
 */
public class RxJava2 {
    private static final String TAG = RxJava2.class.getSimpleName();

    public void easySubscribe() {
        Disposable disposable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onComplete();
            }
        }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                //这里接收数据项
                Log.d(TAG, "接收到数据,value = " + integer);
            }
        }, new Consumer<Throwable>() { // 看subscribe方法参数,这里可以省略
            @Override
            public void accept(Throwable throwable) throws Exception {
                //这里接收onError
            }
        }, new Action() { // 可以省略
            @Override
            public void run() throws Exception {
                //这里接收onComplete
                Log.d(TAG, "onComplete");
            }
        });
    }

    public void easySubscribe3() {
        Disposable disposable = Flowable.create(new FlowableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onNext(3);
                        emitter.onComplete();
                    }
                }, BackpressureStrategy.BUFFER) // 指定背压策略
                .subscribe(new Consumer<Integer>() { // 其它都省略掉
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "接收到数据,value = " + integer);
                    }
                });
    }


    /**
     * 一个使用flatMap的小例子
     */
    private void test(){
        Disposable subscribe = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {

            }
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                List<String> list = new ArrayList<>();
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {

            }
        });
    }
}

三、RxJava操作符——创建操作符

import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

/**
 * RxJava2操作符

 * 创建操作符
 * 基本创建:create
 * 快速创建&发送事件:常用:just/fromArray/fromIterable     非常用:never/empty/error
 * 延迟创建:defer/timer/interval/intervalRange/range/rangeLong
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/7 18:42
 */
public class RxJava3 {
    private static final String TAG = RxJava3.class.getSimpleName();
    // ------------------------------创建操作符:快速创建----------------------------------------

    /**
     * create:普通创建
     */
    public void operator_create() {
        // 1. 通过create创建被观察者对象
        Observable.create(new ObservableOnSubscribe<Integer>() {
            // 2. 在复写的subscribe里定义需要发送的事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }  // 至此,一个被观察者对象(Observable)就创建完毕
        }).subscribe(new Observer<Integer>() {
            // 以下步骤仅为展示一个完整demo,可以忽略
            // 3. 通过通过订阅(subscribe)连接观察者和被观察者
            // 4. 创建观察者 & 定义响应事件的行为
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "接收到了事件" + value);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        });
    }

    /**
     * just--快速创建
     * 特点:直接发送传入的事件
     * 注:最多只能发送10个参数
     */
    public void operate_just() {
        // 1. 创建时传入整型1、2、3、4
        // 在创建后就会发送这些对象,相当于执行了onNext(1)、onNext(2)、onNext(3)、onNext(4)
        Observable.just(1, 2, 3, 4)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }

    /**
     * fromArray:快速创建1个被观察者对象
     * 特点:直接发送传入的数组数据
     * 注意:会将数组中的数据转换为Observable对象
     * 应用场景
     * 1.快速创建 被观察者对象(Observable) & 发送10个以上事件(数组形式)
     * 2.数组元素遍历
     */
    public void operate_fromArray() {
        Integer[] items = {0, 1, 2, 3, 4};
        // 创建被观察者对象(Observable)时传入数组
        // 在创建后就会将该数组转换成Observable & 发送该对象中的所有数据
        Observable.fromArray(items)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }

    /**
     * fromIterable:快速创建1个被观察者对象
     * 特点:直接发送 传入的集合List数据
     * 注意:会将数组中的数据转换为Observable对象
     * 应用场景
     * 1.快速创建 被观察者对象(Observable) & 发送10个以上事件(集合形式)
     * 2.集合元素遍历
     */
    private void operate_fromIterable() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        // 快速发送集合:通过fromIterable()将集合中的对象 / 数据发送出去
        Observable.fromIterable(list).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "接收到了事件" + integer);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        });
    }

    /**
     * 创建操作符的下列方法,一般用于测试使用
     */
    // empty()
    // 该方法创建的被观察者对象发送事件的特点:仅发送Complete事件,直接通知完成
    Observable observable1 = Observable.empty();
    // 即观察者接收后会直接调用onCompleted()

    // error()
    // 该方法创建的被观察者对象发送事件的特点:仅发送Error事件,直接通知异常
    // 可自定义异常
    Observable observable2 = Observable.error(new RuntimeException());
    // 即观察者接收后会直接调用onError()

    // never()
    // 该方法创建的被观察者对象发送事件的特点:不发送任何事件
    Observable observable3 = Observable.never();
    // 即观察者接收后什么都不调用

    // ------------------------------创建操作符:延迟创建----------------------------------------
    // 需求场景
    // 定时操作:在经过了x秒后,需要自动执行y操作
    // 周期性操作:每隔x秒后,需要自动执行y操作

    /**
     * defer:直到有观察者(Observer )订阅时,才动态创建被观察者对象(Observable) & 发送事件
     * 特点:每次订阅后,都会得到一个刚创建的最新的Observable对象,这可以确保Observable对象里的数据是最新的
     */
    Integer i = 10;
    private void operate_defer() {
        // 1. 第1次对i赋值

        // 2. 通过defer 定义被观察者对象
        // 注:此时被观察者对象还没创建
        Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<? extends Integer>>() {
            @Override
            public ObservableSource<? extends Integer> call() throws Exception {
                return Observable.just(i);
            }
        });
        // 2. 第2次对i赋值
        i = 15;

        // 3. 观察者开始订阅
        // 注:此时,才会调用defer()创建被观察者对象(Observable)
        // 因为是在订阅时才创建,所以i值会取第2次的赋值
        observable.subscribe(new Observer<Integer>() {

            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "接收到的整数是" + value);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        });
    }

    /**
     * timer:
     * 特点:延迟指定时间后,发送1个数值(Long类型)
     * 本质:延迟指定时间后,调用一次 onNext()
     * 应用场景:用于延时执行任务,一般用于检测
     */
    private void operate_timer() {
        // 该例子 = 延迟2s后,发送一个long类型数值
        Observable.timer(2, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        // 注:timer操作符默认运行在一个新线程上
        // 也可自定义线程调度器(第3个参数):timer(long,TimeUnit,Scheduler)
    }

    /**
     * interval:
     * 特点:每隔指定时间 就发送事件
     * 发送的事件序列 = 从0开始、无限递增1的的整数序列
     * 应用场景:用于周期执行任务
     */
    private void operate_interval() {
        // 参数说明:
        // 参数1 = 第1次延迟时间;
        // 参数2 = 间隔时间数字;
        // 参数3 = 时间单位;
        Observable.interval(3,1,TimeUnit.SECONDS)
                // 该例子发送的事件序列特点:延迟3s后发送事件,每隔1秒产生1个数字(从0开始递增1,无限个)
                // .take(10) // RxJava提供了take操作符,可以用来限定要接收的数据数,不限制就是无限个,一直发送。
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }
                    // 默认最先调用复写的 onSubscribe()

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG, "接收到了事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }

                });

        // 注:interval默认在computation调度器上执行
        // 也可自定义指定线程调度器(第4个参数):interval(long,long,TimeUnit,Scheduler)
    }

    /**
     * intervalRange:
     * 作用类似于interval,只不过可指定发送的数据的数量
     */
    private void operate_intervalRange(){
        // 参数说明:
        // 参数1 = 事件序列起始点;
        // 参数2 = 事件数量;
        // 参数3 = 第1次事件延迟发送时间;
        // 参数4 = 间隔时间;
        // 参数5 = 间隔时间单位
        Observable.intervalRange(3,10,2, 1, TimeUnit.SECONDS)
                // 该例子发送的事件序列特点:
                // 1. 从3开始,一共发送10个事件;
                // 2. 第1次延迟2s发送,之后每隔2秒产生1个数字(从0开始递增1,无限个)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }
                    // 默认最先调用复写的 onSubscribe()

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG, "接收到了事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }

                });
    }

    /**
     * range:
     * 特点:连续发送 1个事件序列,可指定范围
     * 作用类似于intervalRange,但区别在于:无延迟发送事件
     */
    private void operate_range(){
        // 参数说明:
        // 参数1 = 事件序列起始点;
        // 参数2 = 事件数量;
        // 注:若设置为负数,则会抛出异常
        Observable.range(3,10)
                // 该例子发送的事件序列特点:从3开始发送,每次发送事件递增1,一共发送10个事件
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }
                    // 默认最先调用复写的 onSubscribe()

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }

                });
    }

    // rangeLong()
    // 作用:类似于range(),区别在于该方法支持数据类型 = Long
}

四、RxJava操作符——功能操作符

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.concurrent.TimeUnit;

import io.reactivex.Notification;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.BiPredicate;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;

/**
 * RxJava2操作符
 *
 * 功能操作符
 *
 * 订阅:subscribe
 * 延迟操作:delay
 * 在事件的生命周期中操作:do
 * 错误处理:onErrorReturn/onErrorResumeNext/retry/retryUtil/retryWhen
 * 重复发送操作:repeat/repeatWhen
 * 线程调度:subscribeOn/observeOn (比较重要,放在下一节单独讲)
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/8 10:25
 */
public class RxJava4 {
    private static final String TAG = RxJava4.class.getSimpleName();

    // ------------------------------功能操作符:延迟操作----------------------------------------

    /**
     * delay:
     * 特点:使得被观察者延迟一段时间再发送事件
     * delay具备多个重载方法,具体如下:
     */
    // 1.指定延迟时间
    // 参数1 = 时间;参数2 = 时间单位
    // delay(long delay,TimeUnit unit)

    // 2.指定延迟时间 & 调度器
    // 参数1 = 时间;参数2 = 时间单位;参数3 = 线程调度器
    // delay(long delay,TimeUnit unit,mScheduler scheduler)

    // 3.指定延迟时间 & 错误延迟
    // 错误延迟,即:若存在Error事件,则如常执行,执行后再抛出错误异常
    // 参数1 = 时间;参数2 = 时间单位;参数3 = 错误延迟参数
    // delay(long delay,TimeUnit unit,boolean delayError)

    // 4.指定延迟时间 & 调度器 & 错误延迟
    // 参数1 = 时间;参数2 = 时间单位;参数3 = 线程调度器;参数4 = 错误延迟参数
    // delay(long delay,TimeUnit unit,mScheduler scheduler,boolean delayError): 指定延迟多长时间并添加调度器,错误通知可以设置是否延迟
    private void operate_delay() {
        Observable.just(1, 2, 3)
                .delay(3, TimeUnit.SECONDS) // 延迟3s再发送,由于使用类似,所以此处不作全部展示
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }

    // ------------------------------功能操作符:在事件的生命周期中操作----------------------------------------

    /**
     * do:在某个事件的生命周期中调用(不怎么常用)
     *
     * 有很多个操作符:
     *
     * Observable每次发送数据调用一次:doOnEach
     *
     * Next事件:
     * 执行Next事件前调用doOnNext;
     * 执行Next事件后调用:doAfterNext
     *
     * 发送事件完后调用:
     * 发送错误事件时:doOnError
     * 正常发送事件完后:doOnCompleted
     * 无论正常发送完毕/异常终止:doOnTerminate
     *
     * 最后执行:doFinally
     *
     * 订阅相关:
     * 观察者订阅时调用:doOnSubscribe
     * 观察者取消订阅时调用:doOnUnsubscribe
     */
    private void operate_do() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onNext(3);
                        e.onError(new Throwable("发生错误了"));
                    }
                })
                // 1. 当Observable每发送1次数据事件就会调用1次
                .doOnEach(new Consumer<Notification<Integer>>() {
                    @Override
                    public void accept(Notification<Integer> integerNotification) throws Exception {
                        Log.d(TAG, "doOnEach: " + integerNotification.getValue());
                    }
                })
                // 2. 执行Next事件前调用
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "doOnNext: " + integer);
                    }
                })
                // 3. 执行Next事件后调用
                .doAfterNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "doAfterNext: " + integer);
                    }
                })
                // 4. Observable正常发送事件完毕后调用
                .doOnComplete(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e(TAG, "doOnComplete: ");
                    }
                })
                // 5. Observable发送错误事件时调用
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.d(TAG, "doOnError: " + throwable.getMessage());
                    }
                })
                // 6. 观察者订阅时调用
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        Log.e(TAG, "doOnSubscribe: ");
                    }
                })
                // 7. Observable发送事件完毕后调用,无论正常发送完毕 / 异常终止
                .doAfterTerminate(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e(TAG, "doAfterTerminate: ");
                    }
                })
                // 8. 最后执行
                .doFinally(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e(TAG, "doFinally: ");
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }

    // ------------------------------功能操作符:错误处理----------------------------------------

    /**
     * onErrorReturn
     * 特点:遇到错误时,发送1个特殊事件 & 正常终止
     * 作用:可捕获在它之前发生的异常
     */
    private void operate_onErrorReturn() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Throwable("发生错误了"));
                    }
                })
                .onErrorReturn(new Function<Throwable, Integer>() {
                    @Override
                    public Integer apply(@NonNull Throwable throwable) throws Exception {
                        // 捕捉错误异常
                        Log.e(TAG, "在onErrorReturn处理了错误: " + throwable.toString());
                        return 666;
                        // 发生错误事件后,发送一个"666"事件,最终正常结束
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
        // 打印结果
        // 接收到了事件1
        // 接收到了事件2
        // 在onErrorReturn处理了错误:java.lang.Throwable:发生了错误
        // 接收到了事件666
        // 对Complete事件作出响应
    }


    /**
     * onErrorResumeNext
     * 特点:遇到错误时,发送1个新的Observable
     * 注:
     * 1.onErrorResumeNext拦截的错误 = Throwable;若需拦截Exception请用onExceptionResumeNext()
     * 2.若onErrorResumeNext拦截的错误 = Exception,则会将错误传递给观察者的onError方法
     */
    public void operate_onErrorResumeNext() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Throwable("发生错误了"));
                    }
                })
                .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
                    @Override
                    public ObservableSource<? extends Integer> apply(@NonNull Throwable throwable) throws Exception {
                        // 1. 捕捉错误异常
                        Log.d(TAG, "在onErrorReturn处理了错误: " + throwable);

                        // 2. 发生错误事件后,发送一个新的被观察者 & 发送事件序列
                        return Observable.just(11, 22);
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
        // 打印结果
        // 接收到了事件1
        // 接收到了事件2
        // 在onErrorReturn处理了错误:java.lang.Throwable:发生了错误
        // 接收到了事件11
        // 接收到了事件22
        // 对Complete事件作出响应
    }

    // retry():重试,即当出现错误时,让被观察者(Observable)重新发射数据
    // 特点:
    // 1.接收到 onError()时,重新订阅 & 发送事件
    // 2.Throwable 和 Exception都可拦截

    // 共5种重载方法
    // 1. retry()
    // 作用:出现错误时,让被观察者重新发送数据
    // 注:若一直错误,则一直重新发送

    // 2. retry(long time)
    // 作用:出现错误时,让被观察者重新发送数据(具备重试次数限制)
    // 参数 = 重试次数

    // 3. retry(Predicate predicate)
    // 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送& 持续遇到错误,则持续重试)
    // 参数 = 判断逻辑

    //  4. retry(new BiPredicate<Integer, Throwable>)
    // 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送 & 持续遇到错误,则持续重试
    // 参数 =  判断逻辑(传入当前重试次数 & 异常错误信息)

    // 5. retry(long time,Predicate predicate)
    // 作用:出现错误后,判断是否需要重新发送数据(具备重试次数限制
    // 参数 = 设置重试次数 & 判断逻辑

    /**
     * retry
     */
    private void operate_retry() {
        //  1. retry()
        // 作用:出现错误时,让被观察者重新发送数据
        // 注:若一直错误,则一直重新发送
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Exception("发生错误了"));
                        e.onNext(3);
                    }
                })
                .retry() // 遇到错误时,让被观察者重新发射数据(若一直错误,则一直重新发送
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        //  2. retry(long time)
        // 作用:出现错误时,让被观察者重新发送数据(具备重试次数限制
        // 参数 = 重试次数
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Exception("发生错误了"));
                        e.onNext(3);
                    }
                })
                .retry(3) // 设置重试次数 = 3次
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        //  3. retry(Predicate predicate)
        // 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送& 持续遇到错误,则持续重试)
        // 参数 = 判断逻辑
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Exception("发生错误了"));
                        e.onNext(3);
                    }
                })
                // 拦截错误后,判断是否需要重新发送请求
                .retry(new Predicate<Throwable>() {
                    @Override
                    public boolean test(@NonNull Throwable throwable) throws Exception {
                        // 捕获异常
                        Log.e(TAG, "retry错误: " + throwable.toString());

                        //返回false = 不重新重新发送数据 & 调用观察者的onError结束
                        //返回true = 重新发送请求(若持续遇到错误,就持续重新发送)
                        return true;
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        // 4. retry(new BiPredicate<Integer, Throwable>)
        // 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送 & 持续遇到错误,则持续重试
        // 参数 =  判断逻辑(传入当前重试次数 & 异常错误信息)
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Exception("发生错误了"));
                        e.onNext(3);
                    }
                })

                // 拦截错误后,判断是否需要重新发送请求
                .retry(new BiPredicate<Integer, Throwable>() {
                    @Override
                    public boolean test(@NonNull Integer integer, @NonNull Throwable throwable) throws Exception {
                        // 捕获异常
                        Log.e(TAG, "异常错误 =  " + throwable.toString());

                        // 获取当前重试次数
                        Log.e(TAG, "当前重试次数 =  " + integer);

                        //返回false = 不重新重新发送数据 & 调用观察者的onError结束
                        //返回true = 重新发送请求(若持续遇到错误,就持续重新发送)
                        return true;
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        // 5. retry(long time,Predicate predicate)
        // 作用:出现错误后,判断是否需要重新发送数据(具备重试次数限制
        // 参数 = 设置重试次数 & 判断逻辑
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Exception("发生错误了"));
                        e.onNext(3);
                    }
                })
                // 拦截错误后,判断是否需要重新发送请求
                .retry(3, new Predicate<Throwable>() {
                    @Override
                    public boolean test(@NonNull Throwable throwable) throws Exception {
                        // 捕获异常
                        Log.e(TAG, "retry错误: " + throwable.toString());

                        //返回false = 不重新重新发送数据 & 调用观察者的onError()结束
                        //返回true = 重新发送请求(最多重新发送3次)
                        return true;
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }
    // retryUntil:出现错误后,判断是否需要重新发送数据
    // 若需要重新发送 & 持续遇到错误,则持续重试
    // 作用类似于retry(Predicate predicate)
    // 具体使用类似于retry(Predicate predicate),唯一区别:返回 true 则不重新发送数据事件。此处不作过多描述

    /**
     * retryWhen
     * 遇到错误时,将发生的错误传递给一个新的被观察者(Observable),
     * 并决定是否需要重新订阅原始被观察者(Observable)& 发送事件
     */
    private void operate_when(){
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(1);
                        e.onNext(2);
                        e.onError(new Exception("发生错误了"));
                        e.onNext(3);
                    }
                })
                // 遇到error事件才会回调
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {
                        // 参数Observable<Throwable>中的泛型 = 上游操作符抛出的异常,可通过该条件来判断异常的类型
                        // 返回Observable<?> = 新的被观察者 Observable(任意类型)
                        // 此处有两种情况:
                        // 1. 若 新的被观察者 Observable发送的事件 = Error事件,那么原始Observable则不重新发送事件:
                        // 2. 若 新的被观察者 Observable发送的事件 = Next事件 ,那么原始的Observable则重新发送事件:
                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {
                                // 1. 若返回的Observable发送的事件 = Error事件,则原始的Observable不重新发送事件
                                // 该异常错误信息可在观察者中的onError()中获得
                                return Observable.error(new Throwable("retryWhen终止啦"));

                                // 2. 若返回的Observable发送的事件 = Next事件,则原始的Observable重新发送事件(若持续遇到错误,则持续重试)
                                // return Observable.just(1);
                            }
                        });

                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }
                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应" + e.toString());
                        // 获取异常错误信息
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
        // 打印结果:
        // 接收到了事件1
        // 接收到了事件2
        // 对Error事件作出响应java.lang.Throwable:retryWhen终止啦

        // 如果return Observable.just(1);
        // 则打印结果为:(原始Observable 持续重试)
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件1
        // 接收到了事件2
        // ...
    }

    // ------------------------------功能操作符:重复发送操作----------------------------------------
    /**
     * repeat
     * 特点:重复不断地发送被观察者事件,具备重载方法,可设置重复创建次数
     */
    private void operate_repeat(){
        // 不传入参数 = 重复发送次数 = 无限次
        // repeat();
        // 传入参数 = 重复发送次数有限
        // repeatWhen(Integer int )

        // 注:
        // 1. 接收到.onCompleted()事件后,触发重新订阅 & 发送
        // 2. 默认运行在一个新的线程上

        // 具体使用
        Observable.just(1, 2, 3, 4)
                .repeat(3) // 重复创建次数 =- 3次
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }
    /**
     * repeatWhen:有条件地、重复发送 被观察者事件
     */
    public void operate_repeatWhen(){
        Observable.just(1,2,4).repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
                    @Override
                    // 在Function函数中,必须对输入的 Observable<Object>进行处理,这里我们使用的是flatMap操作符接收上游的数据
                    public ObservableSource<?> apply(@NonNull Observable<Object> objectObservable) throws Exception {
                        // 将原始 Observable 停止发送事件的标识(Complete() /  Error())转换成1个 Object 类型数据传递给1个新被观察者(Observable)
                        // 以此决定是否重新订阅 & 发送原来的 Observable
                        // 此处有2种情况:
                        // 1. 若新被观察者(Observable)返回1个Complete() /  Error()事件,则不重新订阅 & 发送原来的 Observable
                        // 2. 若新被观察者(Observable)返回其余事件,则重新订阅 & 发送原来的 Observable
                        return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Object throwable) throws Exception {

                                // 情况1:若新被观察者(Observable)返回1个Complete() /  Error()事件,则不重新订阅 & 发送原来的 Observable
                                // Observable.empty() = 发送Complete事件,但不会回调观察者的onComplete()
                                // return Observable.empty();

                                // 返回Error事件 = 回调onError()事件,并接收传过去的错误信息。
                                // return Observable.error(new Throwable("不再重新订阅事件"));

                                // 情况2:若新被观察者(Observable)返回其余事件,则重新订阅 & 发送原来的 Observable
                                return Observable.just(1);
                                // 仅仅是作为1个触发重新订阅被观察者的通知,发送的是什么数据并不重要,只要不是Complete() /  Error()事件
                            }
                        });

                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应:" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }

                });
        // 打印结果:
        // 1.新的Observable发送Complete 事件 = 原始Observable停止发送 & 不重新发送
        // 开始采用subscribe连接
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件4

        // 2.新的Observable发送Error 事件 = 原始Observable停止发送 & 不重新发送
        // 开始采用subscribe连接
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件4
        // 对Error事件作出响应:java.lang.Throwable:不再重新订阅事件

        // 3.新的Observable发送其余事件 = 原始Observable重新发送
        // 开始采用subscribe连接
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件2
        // 接收到了事件1
        // 接收到了事件4
        // 接收到了事件2
        // ...
    }
}

五、RxJava操作符——功能操作符

import android.util.Log;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;

/**
 * RxJava2操作符
 *
 * 功能操作符
 *
 * 很多的需求场景,需要在子线程中实现耗时的操作;然后回到主线程实现 UI操作
 * 应用到 RxJava模型中,可理解为:
 * 被观察者Observable在子线程中生产事件(如实现耗时操作等等)
 * 观察者Observer在主线程接收&响应事件(即实现UI操作)
 *
 * 线程调度:subscribeOn/observeOn -采用RxJava内置的线程调度器Scheduler实现
 *
 *          类型                                  含义                      应用场景
 * Schedulers.immediate()                   当前线程 = 不指定线程            默认
 * AndroidSchedulers.mainThread()           Android主线程                  操作UI
 * Schedulers.newThread()                   常规新线程                     耗时等操作
 * Schedulers.io()                          io操作线程                     网络请求、读写文件等io密集型操作
 * Schedulers.computation()                 CPU计算操作线程	             大量计算操作
 *
 * 注:RxJava内部使用 线程池 来维护这些线程,所以线程的调度效率非常高。
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/8 11:48
 */
public class RxJava5 {
    private static final String TAG = RxJava5.class.getSimpleName();
    // 使用说明
    // Observable.subscribeOn(Schedulers.Thread):指定被观察者发送事件的线程(传入RxJava内置的线程类型)
    // Observable.observeOn(Schedulers.Thread):指定观察者接收 & 响应事件的线程(传入RxJava内置的线程类型)

    // 实例使用:通过订阅(subscribe)连接观察者和被观察者
    // observable.subscribeOn(Schedulers.newThread()) // 1. 指定被观察者 生产事件的线程
    // .observeOn(AndroidSchedulers.mainThread())  // 2. 指定观察者 接收 & 响应事件的线程
    // .subscribe(observer); // 3. 最后再通过订阅(subscribe)连接观察者和被观察者


    private Observable<Integer> observable; // 用来举例,所以简单申明变量
    private Observer<Integer> observer;
    /**
     * 注意1:若Observable.subscribeOn()多次指定被观察者 生产事件的线程,则只有第一次指定有效,其余的指定线程无效
     */
    private void operate_subscribeOn(){
        observable.subscribeOn(Schedulers.newThread()) // 第一次指定被观察者线程 = 新线程
                .subscribeOn(AndroidSchedulers.mainThread()) // 第二次指定被观察者线程 = 主线程 (无效)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    /**
     * 注意2:若Observable.observeOn()多次指定观察者 接收 & 响应事件的线程,
     * 则每次指定均有效,即每指定一次,就会进行一次线程的切换
     */
    private void operate_observeOn(){
        observable.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread()) // 第一次指定观察者线程 = 主线程
                .doOnNext(new Consumer<Integer>() { // 生产事件
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "第一次观察者Observer的工作线程是: " + Thread.currentThread().getName());
                    }
                })
                .observeOn(Schedulers.newThread()) // 第二次指定观察者线程 = 新的工作线程
                .subscribe(observer); // 生产事件

        // 注:
        // 1. 整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.doOnNext()>观察者.onNext()>观察者.onComplete()
        // 2. 观察者.onSubscribe()固定在主线程进行
        // 测试结果:每调用一次observeOn(),观察者的线程就会切换一次
    }

    /**
     * 结合Retrofit请求网络的使用实例
     */
    // 1.创建网络请求返回的bean对象
    public static class DataBean {
        // ...
    }
    // 2.创建 用于描述网络请求 的接口
    public interface GetRequest_Interface {
        @GET("...")
        Observable<DataBean> getCall();
    }

    private void withRetrofit(){
        //步骤4:创建Retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("...") // 设置 网络请求 Url
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
                .build();

        // 步骤5:创建 网络请求接口 的实例
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

        // 步骤6:采用Observable<...>形式 对 网络请求 进行封装
        Observable<DataBean> observable = request.getCall();

        // 步骤7:发送网络请求
        observable.subscribeOn(Schedulers.io())               // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  // 回到主线程 处理请求结果
                .subscribe(new Observer<DataBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(DataBean result) {
                        // 对返回的数据进行处理
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "请求失败");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "请求成功");
                    }
                });
    }

    /**
     * 其它问题
     * 背景:在发送网络请求时,退出当前Activity
     * 冲突:此时如果回到主线程更新 UI,App会崩溃
     * 解决方案:当 Activity退出时,调用 Disposable.dispose()切断观察者和被观察者的连接,使得观察者无法收到事件 & 响应事件
     * 当出现多个Disposable时,可采用RxJava内置容器CompositeDisposable进行统一管理
     */
    // 添加Disposable到CompositeDisposable容器
    // CompositeDisposable.add()

    // 清空CompositeDisposable容器
    // CompositeDisposable.clear()
}

六、RxJava操作符——过滤操作符

import android.util.Log;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;

/**
 * RxJava2操作符
 *
 * 过滤操作符
 *
 * 根据指定条件过滤事件:      filter/ofType/skip/skipLast/distinct/distinctUtilChanged
 * 根据指定事件数量过滤事件:   take/takeLst
 * 根据指定时间过滤事件:      debounce/sample/throttleFirst/throttleLast..
 * 根据指定事件位置过滤事件:   firstElement/lastElement/elementAt/elementAtOrError
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/8 14:15
 */
public class RxJava6 {
    private static final String TAG = RxJava6.class.getSimpleName();
    // ------------------------------过滤操作符:根据指定条件过滤事件----------------------------------------
    /**
     * filter
     */
    private void operate_filter() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                // 1. 发送5个事件
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
                emitter.onNext(5);
            }

            // 2. 采用filter()变换操作符
        }).filter(new Predicate<Integer>() {
            // 根据test()的返回值 对被观察者发送的事件进行过滤 & 筛选
            // a. 返回true,则继续发送
            // b. 返回false,则不发送(即过滤)
            @Override
            public boolean test(Integer integer) throws Exception {
                return integer > 3;
                // 本例子 = 过滤了整数≤3的事件
            }
        }).subscribe(new Observer<Integer>() {

            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "过滤后得到的事件是:" + value);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        });
    }

    /**
     * ofType:过滤 特定数据类型的数据
     */
    private void operate_ofType() {
        Disposable disposable = Observable.just(1, "Carson", 3, "Ho", 5)
                .ofType(Integer.class) // 筛选出 整型数据
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的整型事件元素是: " + integer);
                    }
                });
    }

    /**
     * skip/skipLast:跳过某个事件
     */
    private void operate_skip() {
        // 使用1:根据顺序跳过数据项
        Disposable disposable = Observable.just(1, 2, 3, 4, 5)
                .skip(1) // 跳过正序的前1项
                .skipLast(2) // 跳过正序的后2项
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的整型事件元素是: " + integer);
                    }
                });

        // 使用2:根据时间跳过数据项
        // 发送事件特点:发送数据0-5,每隔1s发送一次,每次递增1;第1次发送延迟0s
        Disposable disposable1 = Observable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)
                .skip(1, TimeUnit.SECONDS) // 跳过第1s发送的数据
                .skipLast(1, TimeUnit.SECONDS) // 跳过最后1s发送的数据
                .subscribe(new Consumer<Long>() {

                    @Override
                    public void accept(Long along) throws Exception {
                        Log.d(TAG, "获取到的整型事件元素是: " + along);
                    }
                });
    }

    /**
     * distinct/distinctUntilChanged :过滤事件序列中重复的事件 / 连续重复的事件
     */
    private void operate_distinct() {
        // 使用1:过滤事件序列中重复的事件
        Disposable disposable = Observable.just(1, 2, 3, 1, 2)
                .distinct()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "不重复的整型事件元素是: " + integer);
                    }
                });

        // 使用2:过滤事件序列中 连续重复的事件
        // 下面序列中,连续重复的事件 = 3、4
        Disposable disposable1 = Observable.just(1, 2, 3, 1, 2, 3, 3, 4, 4)
                .distinctUntilChanged()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "不连续重复的整型事件元素是: " + integer);
                    }
                });
    }

    // ------------------------------过滤操作符:根据指定事件数量过滤事件----------------------------------------
    /**
     * take :根据 指定事件数量 过滤事件(指定观察者最多能接收到的事件数量)
     */
    private void operate_take() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        // 1. 发送5个事件
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onNext(3);
                        emitter.onNext(4);
                        emitter.onNext(5);
                    }
                    // 采用take()变换操作符
                    // 指定了观察者只能接收2个事件
                }).take(2)
                .subscribe(new Observer<Integer>() {

                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "过滤后得到的事件是:" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        // 实际上,可理解为:被观察者还是发送了5个事件,只是因为操作符的存在拦截了3个事件,最终观察者接收到的是2个事件
    }

    /**
     * taskLast:指定观察者只能接收到被观察者发送的最后几个事件
     */
    private void operate_takeLast() {
        Observable.just(1, 2, 3, 4, 5)
                .takeLast(3) //指定观察者只能接受被观察者发送的3个事件
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "过滤后得到的事件是:" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }

    // ------------------------------过滤操作符:根据指定时间过滤事件----------------------------------------
    /**
     * throttleFirst/throttleLast:根据 指定时间 过滤事件
     * 在某段时间内,只发送该段时间内第1次事件 / 最后1次事件
     * 如,1段时间内连续点击按钮,但只执行第1次的点击操作
     */
    private void operate_throttle() {
        //  在某段时间内,只发送该段时间内第1次事件 
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        // 隔段事件发送时间
                        e.onNext(1);
                        Thread.sleep(500);

                        e.onNext(2);
                        Thread.sleep(400);

                        e.onNext(3);
                        Thread.sleep(300);

                        e.onNext(4);
                        Thread.sleep(300);

                        e.onNext(5);
                        Thread.sleep(300);

                        e.onNext(6);
                        Thread.sleep(400);

                        e.onNext(7);
                        Thread.sleep(300);
                        e.onNext(8);

                        Thread.sleep(300);
                        e.onNext(9);

                        Thread.sleep(300);
                        e.onComplete();
                    }
                }).throttleFirst(1, TimeUnit.SECONDS)//每1秒中采用数据
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        //  在某段时间内,只发送该段时间内最后1次事件
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        // 隔段事件发送时间
                        e.onNext(1);
                        Thread.sleep(500);

                        e.onNext(2);
                        Thread.sleep(400);

                        e.onNext(3);
                        Thread.sleep(300);

                        e.onNext(4);
                        Thread.sleep(300);

                        e.onNext(5);
                        Thread.sleep(300);

                        e.onNext(6);
                        Thread.sleep(400);

                        e.onNext(7);
                        Thread.sleep(300);
                        e.onNext(8);

                        Thread.sleep(300);
                        e.onNext(9);

                        Thread.sleep(300);
                        e.onComplete();
                    }
                }).throttleLast(1, TimeUnit.SECONDS)//每1秒中采用数据
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }
    // Sample:在某段时间内,只发送该段时间内最新(最后)1次事件
    // 与 throttleLast 操作符类似

    /**
     * throttleWithTimeout/debounce
     * 发送数据事件时,若2次发送事件的间隔<指定时间,就会丢弃前一次的数据,
     * 直到指定时间内都没有新数据发射时才会发送后一次的数据
     */
    private void operate_throttleWithTimeout(){
        Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        // 隔段事件发送时间
                        e.onNext(1);
                        Thread.sleep(500);
                        e.onNext(2); // 1和2之间的间隔小于指定时间1s,所以前1次数据(1)会被抛弃,2会被保留
                        Thread.sleep(1500);  // 因为2和3之间的间隔大于指定时间1s,所以之前被保留的2事件将发出
                        e.onNext(3);
                        Thread.sleep(1500);  // 因为3和4之间的间隔大于指定时间1s,所以3事件将发出
                        e.onNext(4);
                        Thread.sleep(500); // 因为4和5之间的间隔小于指定时间1s,所以前1次数据(4)会被抛弃,5会被保留
                        e.onNext(5);
                        Thread.sleep(500); // 因为5和6之间的间隔小于指定时间1s,所以前1次数据(5)会被抛弃,6会被保留
                        e.onNext(6);
                        Thread.sleep(1500); // 因为6和Complete实践之间的间隔大于指定时间1s,所以之前被保留的6事件将发出

                        e.onComplete();
                    }
                }).throttleWithTimeout(1, TimeUnit.SECONDS)//每1秒中采用数据
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件"+ value  );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

    }
    // ------------------------------过滤操作符:根据指定事件位置过滤事件----------------------------------------

    /**
     * firstElement/lastElement:仅选取第1个元素 / 最后一个元素
     */
    private void operate_element(){
        // 获取第1个元素
        Disposable disposable = Observable.just(1, 2, 3, 4, 5)
                .firstElement()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的第一个事件是: " + integer);
                    }
                });

        // 获取最后1个元素
        Disposable disposable1 = Observable.just(1, 2, 3, 4, 5)
                .lastElement()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的最后1个事件是: " + integer);
                    }
                });
    }
    // elementAt:指定接收某个元素(通过 索引值 确定)
    // 允许越界,即获取的位置索引 > 发送事件序列长度

    // elementAtOrError:在elementAt()的基础上,当出现越界情况(即获取的位置索引 > 发送事件序列长度)时,即抛出异常
}

七、RxJava操作符——组合/合并操作符

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * RxJava2操作符
 * 
 * 组合/合并操作符
 * 
 * 组合多个被观察者:
 * 按顺序contact,contactArray
 * 按时间merge,mergeArray
 * 错误处理contactDelayError,mergeDelayError
 * 合并多个事件:
 * 按数量zip
 * 按时间combineLatest,combineLatestDelayError
 * 合并成1个事件发送:reduce/collect
 * 发送前追加发送事件:startWidth/startWidthArray
 * 统计发送事件数量:count
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/8 16:27
 */
public class RxJava7 {
    private static final String TAG = RxJava7.class.getSimpleName();
    // ------------------------------组合操作符:组合多个被观察者----------------------------------------

    /**
     * concat/concatArray
     * 特点:组合多个被观察者一起发送数据,合并后 按发送顺序串行执行
     * 二者区别:组合被观察者的数量,concat组合被观察者数量≤4个,而concatArray则可>4个
     */
    private void operate_contact() {
        // concat():组合多个被观察者(≤4个)一起发送数据
        // 注:串行执行
        Observable.concat(Observable.just(1, 2, 3),
                        Observable.just(4, 5, 6),
                        Observable.just(7, 8, 9),
                        Observable.just(10, 11, 12))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        // concatArray():组合多个被观察者一起发送数据(可>4个)
        // 注:串行执行
        Observable.concatArray(Observable.just(1, 2, 3),
                        Observable.just(4, 5, 6),
                        Observable.just(7, 8, 9),
                        Observable.just(10, 11, 12),
                        Observable.just(13, 14, 15))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }

    /**
     * merge/mergeArray:组合多个被观察者一起发送数据,合并后 按时间线并行执行
     * 二者区别:
     * 1.组合被观察者的数量,即merge组合被观察者数量≤4个,而mergeArray则可>4个
     * 2.区别上述concat操作符:同样是组合多个被观察者一起发送数据,但concat操作符合并后是按发送顺序串行执行
     */
    private void operate_merge() {
        // merge():组合多个被观察者(<4个)一起发送数据
        // 注:合并后按照时间线并行执行
        Observable.merge(
                        Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
                        Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS)) // 从2开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        // mergeArray() = 组合4个以上的被观察者一起发送数据,此处不作过多演示,类似concatArray()
        // 输出结果 = 0,2 -> 1,3 -> 2,4
    }

    // concatDelayError/mergeDelayError
    // 使用contact/merge,若其中一个时间error后,则马上回终止事件发送
    // 若希望onError事件推迟到被观察者事件发送完才触发,可以使用concatDelayError/mergeDelayError操作符

    // ------------------------------合并操作符:合并多个事件----------------------------------------
    // 该类型的操作符主要是对多个被观察者中的事件进行合并处理。(注意:不是Observable,是事件)

    /**
     * zip
     * 合并 多个被观察者(Observable)发送的事件,生成一个新的事件序列(即组合过后的事件序列),并最终发送
     * 注意:
     * 1.事件组合方式 = 严格按照原先事件序列 进行对位合并
     * 2.最终合并的事件数量 = 多个被观察者(Observable)中数量最少的数量
     */
    private void operate_zip() {
        // 创建第1个被观察者
        Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                Log.d(TAG, "被观察者1发送了事件1");
                emitter.onNext(1);
                // 为了方便展示效果,所以在发送事件后加入2s的延迟
                Thread.sleep(1000);

                Log.d(TAG, "被观察者1发送了事件2");
                emitter.onNext(2);
                Thread.sleep(1000);

                Log.d(TAG, "被观察者1发送了事件3");
                emitter.onNext(3);
                Thread.sleep(1000);

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io()); // 设置被观察者1在工作线程1中工作

        // 创建第2个被观察者
        Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.d(TAG, "被观察者2发送了事件A");
                emitter.onNext("A");
                Thread.sleep(1000);

                Log.d(TAG, "被观察者2发送了事件B");
                emitter.onNext("B");
                Thread.sleep(1000);

                Log.d(TAG, "被观察者2发送了事件C");
                emitter.onNext("C");
                Thread.sleep(1000);

                Log.d(TAG, "被观察者2发送了事件D");
                emitter.onNext("D");
                Thread.sleep(1000);

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.newThread());// 设置被观察者2在工作线程2中工作
        // 假设不作线程控制,则该两个被观察者会在同一个线程中工作,即发送事件存在先后顺序,而不是同时发送

        // 使用zip变换操作符进行事件合并
        // 注:创建BiFunction对象传入的第3个参数 = 合并后数据的数据类型
        Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
                    @Override
                    public String apply(Integer integer, String s) throws Exception {
                        return null;
                    }
                }
        ).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe");
            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, "最终接收到的事件 =  " + s);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete");
            }
        });
        // 结果:
        // onSubscribe
        // 被观察者1发送了事件1
        // 被观察者2发送了事件A
        // 最终接收到的事件 = 1A
        // 被观察者1发送了事件2
        // 被观察者2发送了事件B
        // 最终接收到的事件 = 2B
        // ...
    }

    /**
     * combineLatest
     * 当两个Observables中的任何一个发送了数据后,将先发送了数据的Observables 的最新(最后)一个数据 与 另外一个Observable发送的每个数据结合,
     * 最终基于该函数的结果发送数据
     */
    private void operate_combineLast() {
        Disposable disposable = Observable.combineLatest(
                // 第1个发送数据事件的Observable
                Observable.just(1L, 2L, 3L),
                // 第2个发送数据事件的Observable:从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
                Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS),
                new BiFunction<Long, Long, Long>() {
                    @Override
                    public Long apply(Long o1, Long o2) throws Exception {
                        // o1 = 第1个Observable发送的最新(最后)1个数据
                        // o2 = 第2个Observable发送的每1个数据
                        Log.e(TAG, "合并的数据是: " + o1 + " " + o2);
                        return o1 + o2;
                        // 合并的逻辑 = 相加
                        // 即第1个Observable发送的最后1个数据 与 第2个Observable发送的每1个数据进行相加
                    }
                }).subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long s) throws Exception {
                Log.e(TAG, "合并的结果是: " + s);
            }
        });
        // 合并的数据是:3 0
        // 合并的结果是:3
        // 合并的数据是:3 1
        // 合并的结果是:4
        // 合并的数据是:3 2
        // 合并的结果是:5
    }

    // combineLatestDelayError;作用类似于concatDelayError() / mergeDelayError() ,即错误处理,此处不作过多描述

    /**
     * reduce
     * 把被观察者需要发送的事件聚合成1个事件 & 发送
     * 聚合的逻辑根据需求撰写,但本质都是前2个数据聚合,然后与后1个数据继续进行聚合,依次类推
     */
    private void operate_reduce() {
        Disposable disposable = Observable.just(1, 2, 3, 4)
                .reduce(new BiFunction<Integer, Integer, Integer>() {
                    // 在该复写方法中复写聚合的逻辑
                    @Override
                    public Integer apply(@NonNull Integer s1, @NonNull Integer s2) throws Exception {
                        Log.e(TAG, "本次计算的数据是: " + s1 + " 乘 " + s2);
                        return s1 * s2;
                        // 本次聚合的逻辑是:全部数据相乘起来
                        // 原理:第1次取前2个数据相乘,之后每次获取到的数据 = 返回的数据x原始下1个数据每
                    }
                }).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer s) throws Exception {
                        Log.e(TAG, "最终计算的结果是: " + s);
                    }
                });
        // 本次计算的数据是:1 乘 2
        // 本次计算的数据是:2 乘 3
        // 本次计算的数据是:6 乘 4
        // 最终计算的结果是:24
    }

    /**
     * collect
     * 将被观察者Observable发送的数据事件收集到一个数据结构里
     */
    private void operate_collect() {
        Disposable disposable = Observable.just(1, 2, 3, 4, 5, 6)
                .collect(
                        // 1. 创建数据结构(容器),用于收集被观察者发送的数据
                        new Callable<ArrayList<Integer>>() {
                            @Override
                            public ArrayList<Integer> call() throws Exception {
                                return new ArrayList<>();
                            }
                            // 2. 对发送的数据进行收集
                        }, new BiConsumer<ArrayList<Integer>, Integer>() {
                            @Override
                            public void accept(ArrayList<Integer> list, Integer integer)
                                    throws Exception {
                                // 参数说明:list = 容器,integer = 后者数据
                                list.add(integer);
                                // 对发送的数据进行收集
                            }
                        }).subscribe(new Consumer<ArrayList<Integer>>() {
                    @Override
                    public void accept(@NonNull ArrayList<Integer> s) throws Exception {
                        Log.e(TAG, "本次发送的数据是: " + s);
                    }
                });
        // 本次发送的数据是:[1,2,3,4,5,6]
    }

    // ------------------------------发送事件前追加发送事件---------------------------------------

    /**
     * startWith/startWithArray
     * 在一个被观察者发送事件前,追加发送一些数据 / 一个新的被观察者
     */
    private void operate_startWith() {
        //  在一个被观察者发送事件前,追加发送一些数据 
        // 注:追加数据顺序 = 后调用先追加
        Observable.just(4, 5, 6)
                .startWith(0)  // 追加单个数据 = startWith()
                .startWithArray(1, 2, 3) // 追加多个数据 = startWithArray()
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });

        //  在一个被观察者发送事件前,追加发送被观察者 & 发送数据
        // 注:追加数据顺序 = 后调用先追加
        Observable.just(4, 5, 6)
                .startWith(Observable.just(1, 2, 3))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "接收到了事件" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
        // 接收到了事件1
        // 接收到了事件2
        // 接收到了事件3
        // 接收到了事件0
        // 接收到了事件4
        // 接收到了事件5
        // 接收到了事件6
    }
    /**
     * count
     * 统计被观察者发送事件的数量
     */
    private void operate_count(){
        // 注:返回结果 = Long类型
        Disposable disposable = Observable.just(1, 2, 3, 4)
                .count()
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.e(TAG, "发送的事件数量 =  " + aLong);
                    }
                });
    }
}

八、RxJava操作符——变换操作符

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

/**
 * RxJava2操作符
 * 
 * 变换操作符
 * 
 * 嵌套回调:map/flatMap/contactMap/buffer
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/8 17:14
 */
public class RxJava8 {
    private static final String TAG = RxJava8.class.getSimpleName();

    /**
     * map:数据类型转换
     * 对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件
     * 即, 将被观察者发送的事件转换为任意的类型事件。
     */
    private void operate_map() {
        // 采用RxJava基于事件流的链式操作
        Disposable disposable = Observable.create(new ObservableOnSubscribe<Integer>() {

            // 1. 被观察者发送事件 = 参数为整型 = 1、2、3
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
            // 2. 使用Map变换操作符中的Function函数对被观察者发送的事件进行统一变换:整型变换成字符串类型
        }).map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Exception {
                return "使用 Map变换操作符 将事件" + integer + "的参数从 整型" + integer + " 变换成 字符串类型" + integer;
            }
        }).subscribe(new Consumer<String>() {

            // 3. 观察者接收事件时,是接收到变换后的事件 = 字符串类型
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });
    }

    /**
     * flatMap
     * 将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
     * 
     * 原理
     * 1.为事件序列中每个事件都创建一个 Observable 对象;
     * 2.将对每个 原始事件 转换后的 新事件 都放入到对应 Observable对象;
     * 3.将新建的每个Observable 都合并到一个 新建的、总的Observable 对象;
     * 4.新建的、总的Observable 对象 将 新合并的事件序列 发送给观察者(Observer)
     * 
     * 应用场景
     * 无序的将被观察者发送的整个事件序列进行变换
     */
    private void operate_flatMap() {
        // 采用RxJava基于事件流的链式操作
        Disposable subscribe = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
            // 采用flatMap()变换操作符
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("我是事件 " + integer + "拆分后的子事件" + i);
                    // 通过flatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
                    // 最终合并,再发送给被观察者
                }
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });
    }

    /**
     * contactMap
     * 与FlatMap()的 区别在于:拆分 & 重新合并生成的事件序列 的顺序 = 被观察者旧序列生产的顺序
     * 
     * 应用场景
     * 有序的将被观察者发送的整个事件序列进行变换
     */
    private void operate_contactMap() {
        // 采用RxJava基于事件流的链式操作
        Disposable disposable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }

            // 采用concatMap()变换操作符
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("我是事件 " + integer + "拆分后的子事件" + i);
                    // 通过concatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件
                    // 最终合并,再发送给被观察者
                }
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });
    }

    /**
     * buffer
     * 定期从 被观察者(Observable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送
     * 应用场景
     * 缓存被观察者发送的事件
     */
    private void operate_buffer() {
        // 被观察者 需要发送5个数字
        Observable.just(1, 2, 3, 4, 5)
                .buffer(3, 1) // 设置缓存区大小 & 步长
                // 缓存区大小 = 每次从被观察者中获取的事件数量
                // 步长 = 每次获取新事件的数量
                .subscribe(new Observer<List<Integer>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }
                    @Override
                    public void onNext(List<Integer> stringList) {
                        Log.d(TAG, " 缓存区里的事件数量 = " +  stringList.size());
                        for (Integer value : stringList) {
                            Log.d(TAG, " 事件 = " + value);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应" );
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "对Complete事件作出响应");
                    }
                });
    }
}

九、RxJava操作符——条件/布尔操作符

import android.util.Log;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;

/**
 * RxJava2操作符
 *
 * 条件/布尔操作符
 * all/exists/contains/isEmpty/takeWhile/takeUntil/skipWhile/skipUntil/amb/defaultEmpty
 *
 * @description:
 * @author:mengyue.liu
 * @time: 2022/7/8 17:27
 */
public class RxJava9 {
    private static final String TAG = RxJava9.class.getSimpleName();

    /**
     * all:判断发送的每项数据是否都满足 设置的函数条件
     * 若满足,返回 true;否则,返回 false
     */
    private void operate_all(){
        Disposable disposable = Observable.just(1, 2, 3, 4, 5, 6)
                .all(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return (integer <= 10);
                        // 该函数用于判断Observable发送的10个数据是否都满足integer<=10
                    }
                }).subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        Log.d(TAG, "result is " + aBoolean);
                        // 输出返回结果
                    }
                });
        // true
    }
    /**
     * takeWhile
     * 作用:判断发送的每项数据是否满足 设置函数条件
     * 若发送的数据满足该条件,则发送该项数据;否则不发送
     */
    private void operate_takeWhile(){
        // 1. 每1s发送1个数据 = 从0开始,递增1,即0、1、2、3
        Observable.interval(1, TimeUnit.SECONDS)
                // 2. 通过takeWhile传入一个判断条件
                .takeWhile(new Predicate<Long>(){
                    @Override
                    public boolean test( Long integer) throws Exception {
                        return (integer<3);
                        // 当发送的数据满足<3时,才发送Observable的数据
                    }
                }).subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG,"发送了事件 "+ value);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }

    /**
     * skipWhile:直到该判断条件 = false时,才开始发送Observable的数据
     */
    private void operate_skipWhile(){
        // 1. 每隔1s发送1个数据 = 从0开始,每次递增1
        Observable.interval(1, TimeUnit.SECONDS)
                // 2. 通过skipWhile()设置判断条件
                .skipWhile(new Predicate<Long>(){
                    @Override
                    public boolean test( Long aLong) throws Exception {
                        return (aLong<5);
                        // 直到判断条件不成立 = false = 发射的数据≥5,才开始发送数据
                    }
                }).subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG,"发送了事件 "+ value);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }

    // takeUntil:执行到某个条件时,停止发送事件。
    private void operate_takeUtil(){
        // 1. 每1s发送1个数据 = 从0开始,递增1,即0、1、2、3
        Observable.interval(1, TimeUnit.SECONDS)
                // 2. 通过takeUntil的Predicate传入判断条件
                .takeUntil(new Predicate<Long>(){
                    @Override
                    public boolean test( Long integer) throws Exception {
                        return (integer>3);
                        // 返回true时,就停止发送事件
                        // 当发送的数据满足>3时,就停止发送Observable的数据
                    }
                }).subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG,"发送了事件 "+ value);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
        // 该判断条件也可以是Observable,即 等到 takeUntil传入的Observable开始发送数据,(原始)第1个Observable的数据停止发送数据
    }

    // skipUntil:等到 skipUntil传入的Observable开始发送数据,(原始)第1个Observable的数据才开始发送数据

    // SequenceEqual:判定两个Observables需要发送的数据是否相同.相同,返回 true;否则,返回 false

    // contains:判断发送的数据中是否包含指定数据
    // 若包含,返回 true;否则,返回 false
    // 内部实现 = exists()

    // isEmpty:判断发送的数据是否为空
    // 若为空,返回 true;否则,返回 false

    // amb:当需要发送多个 Observable时,只发送 先发送数据的Observable的数据,而其余 Observable则被丢弃。

    // defaultIfEmpty:在不发送任何有效事件( Next事件)、仅发送了 Complete 事件的前提下,发送一个默认值
}

十、Rxjava背压策略

待完成

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值