RXJava2 全面学习笔记 (上)

本文篇幅较长 建议收藏起来等时间空闲详细阅读
本篇文章主要是一份学习笔记

RXJava入门教程

定义

RxJava是一个在java VM上可以使用可观测的序列来组成异步的,基于事件的程序库, RxJava是一个基于时间流.实现异步操作的库

作用

实现异步 类似于android中的ASyncTask,Handler作用

特点

基于事件流的链式调用,保持代码简洁&优雅

原理分析

生活场景: 去吃饭.

开始
坐下
找到服务员
点菜
向厨房下单
得到客户点的菜单
根据顺序做菜
送给用户餐桌
  • RxJava原理是基于一种扩展的观察者模式
  • RxJava的扩展观察者模式4个角色
角色作用类比
被观察者Observable产生事件顾客
观察者Observer接受事件,并作出相应动作厨房
订阅者Subscribe连接被观察者&观察者服务员
事件Event被观察者*观察者 沟通的载体菜式

原理总结为被观察者通过订阅者按顺序发送事件给观察者,观察者按事件接受事件的顺序&做出对应的响应动作.

分步骤实现
  • 创建被观察者(Observable)并且产生事件

    • 即顾客到饭店–>坐到位置–>点菜 具体实现;

      // 1. 创建被观察者 Observable 对象
              Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
                // create() 是 RxJava 最基本的创造事件序列的方法
                // 此处传入了一个 OnSubscribe 对象参数
                // 当 Observable 被订阅时,OnSubscribe 的 call() 方法会自动被调用,即事件序列就会依照设定依次被触发
                // 即观察者会依次调用对应事件的复写方法从而响应事件
                // 从而实现被观察者调用了观察者的回调方法 & 由被观察者向观察者的事件传递,即观察者模式
      
              // 2. 在复写的subscribe()里定义需要发送的事件
                  @Override
                  public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                      // 通过 ObservableEmitter类对象产生事件并通知观察者
                      // ObservableEmitter类介绍
                          // a. 定义:事件发射器
                          // b. 作用:定义需要发送的事件 & 向观察者发送事件
                      emitter.onNext(1);
                      emitter.onNext(2);
                      emitter.onNext(3);
                      emitter.onComplete();
                  }
              });
      
      <--扩展:RxJava 提供了其他方法用于 创建被观察者对象Observable -->
      // 方法1:just(T...):直接将传入的参数依次发送出来
        Observable observable = Observable.just("A", "B", "C");
        // 将会依次调用:
        // onNext("A");
        // onNext("B");
        // onNext("C");
        // onCompleted();
      
      // 方法2:from(T[]) / from(Iterable<? extends T>) : 将传入的数组 / Iterable 拆分成具体对象后,依次发送出来
        String[] words = {"A", "B", "C"};
        Observable observable = Observable.from(words);
        // 将会依次调用:
        // onNext("A");
        // onNext("B");
        // onNext("C");
        // onCompleted();
      
      
  • 创建观察者(Observer)并且定义响应事件行为

    发生的事件类型包括 Next事件,complete事件,error事件

    事件类型定义作用使用规则使用方法
    Next普通时间向观察者发送需要响应事件的信号被观察者可无限次的发送Next事件,观察者无限次接受事件onNext
    Complete事件队列完结,(事件)标志,被观察者,不在发送普通事件1. 当被观察者发送了一个Complete事件后被观察者在complete事件后的事件将会继续发送,但是观察者收到complete事件后将不会再接受任何事件
    2.被观察者可以不发送complete事件
    onCompleted()
    error事件队列异常 (事件)标志 事件处理过程中出现异常1. 当被观察者发送一个Error事件后,被观察者在error事件后的事件将会继续发送,但是观察者收到error事件后将不会继续接受任何事件
    2.被观察者可以不发送Error事件
    onErrror()

    在一个正确运行的事件序列中:onComplete和onError事件相互排斥,只能拥有唯一的一个事件.

    具体实现:

    <--方式1:采用Observer 接口 -->
            // 1. 创建观察者 (Observer )对象
            Observer<Integer> observer = new Observer<Integer>() {
            // 2. 创建对象时通过对应复写对应事件方法 从而 响应对应事件
    
                // 观察者接收事件前,默认最先调用复写 onSubscribe()
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(TAG, "开始采用subscribe连接");
                }
                
                // 当被观察者生产Next事件 & 观察者接收到时,会调用该复写方法 进行响应
                @Override
                public void onNext(Integer value) {
                    Log.d(TAG, "对Next事件作出响应" + value);
                }
    
                // 当被观察者生产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 接口进行了扩展
    
    // 1. 创建观察者 (Observer )对象
    Subscriber<String> subscriber = new Subscriber<Integer>() {
    
    // 2. 创建对象时通过对应复写对应事件方法 从而 响应对应事件
                // 观察者接收事件前,默认最先调用复写 onSubscribe()
                @Override
                public void onSubscribe(Subscription s) {
                    Log.d(TAG, "开始采用subscribe连接");
                }
    
                // 当被观察者生产Next事件 & 观察者接收到时,会调用该复写方法 进行响应
                @Override
                public void onNext(Integer value) {
                    Log.d(TAG, "对Next事件作出响应" + value);
                }
    
                // 当被观察者生产Error事件& 观察者接收到时,会调用该复写方法 进行响应
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "对Error事件作出响应");
                }
    
                // 当被观察者生产Complete事件& 观察者接收到时,会调用该复写方法 进行响应
                @Override
                public void onComplete() {
                    Log.d(TAG, "对Complete事件作出响应");
                }
            };
    
    
    <--特别注意:2种方法的区别,即Subscriber 抽象类与Observer 接口的区别 -->
    // 相同点:二者基本使用方式完全一致(实质上,在RxJava的 subscribe 过程中,Observer总是会先被转换成Subscriber再使用)
    // 不同点:Subscriber抽象类对 Observer 接口进行了扩展,新增了两个方法:
        // 1. onStart():在还未响应事件前调用,用于做一些初始化工作
        // 2. unsubscribe():用于取消订阅。在该方法被调用后,观察者将不再接收 & 响应事件
        // 调用该方法前,先使用 isUnsubscribed() 判断状态,确定被观察者Observable是否还持有观察者Subscriber的引用,如果引用不能及时释放,就会出现内存泄露
    
  • 通过订阅者(subscribe)连接被观察者和观察者

    即顾客点菜–>服务员下单到厨房–>厨房做菜

    具体实现

    observable.subscribe(observer)
      
      //扩展说明
      <-- Observable.subscribe(Subscriber) 的内部实现 -->
    
    public Subscription subscribe(Subscriber subscriber) {
        subscriber.onStart();
        // 步骤1中 观察者  subscriber抽象类复写的方法,用于初始化工作
        onSubscribe.call(subscriber);
        // 通过该调用,从而回调观察者中的对应方法从而响应被观察者生产的事件
        // 从而实现被观察者调用了观察者的回调方法 & 由被观察者向观察者的事件传递,即观察者模式
        // 同时也看出:Observable只是生产事件,真正的发送事件是在它被订阅的时候,即当 subscribe() 方法执行时.
    

RxJava操作符


基本操作
  1. create()

    作用: 完整创建一个被观察者(Observable),最基本的操作符

    具体使用:

      Observable.create(new ObservableOnSubscribe<Integer>() {
                @Override
                public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                    emitter.onNext(1);
                    emitter.onNext(3);
                    emitter.onNext(4);
                    emitter.onComplete();
                }
            }).subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.e(TAG, "onSubscribe");
                }
    
                @Override
                public void onNext(Integer integer) {
                    Log.e(TAG, "integer" + integer);
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "onError");
                }
    
                @Override
                public void onComplete() {
                    Log.e(TAG, "onComplete");
                }
            });
    //依次执行 onSubscribe-->integer1-->integer2-->integer3-->onComplete 如果那个步骤出错会执行onError
    
  2. 快速创建&&发送事件

    • just()

      快速创建被观察者对象(observable),直接传入发送的事件,最多可发送10个事件

    • fromArray()

      快速创建被观察者对象(observable),直接传入数组发送事件,只能传入数组,传入list默认为一个事件

    • fromltearable()

      快速创建被观察对象(observable) 直接传入集合对象,

    • never()

      不发送任何事件

    • empty()

      该方法创建的被观察者对象发送事件的特点,仅仅执行Complete事件,直接通知完成

    • error()

  3. 延迟创建

    • defer()

      直到观察者(observer)订阅时,才会动态创建被观察者对象(observable)&发送事件

      • 通过observable工厂方法创建被观察者对象(observable)

      • 每次订阅都会得到一个刚创建的最新的observable对象,这可以确保observable对象里的数据是最新的.

         i = 20;//首次初始化
                Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> call() throws Exception {
                        return Observable.just(i); //执行i=20;
                    }
                });
                i = 30;//重新赋值
        				//订阅者订阅事件 得到log是 i=30, 
                observable.subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG, "连接suber");
                    }
        
                    @Override
                    public void onNext(Integer integer) {
                        Log.e(TAG, integer + "");
                    }
        
                    @Override
                    public void onError(Throwable e) {
        
                    }
        
                    @Override
                    public void onComplete() {
                        Log.e(TAG, "完成整个流程..");
                    }
                });
        
    • timer()

      作用:快速创建一个被观察者对象(observable) 发送事件的特点:延迟指定时间后,发送一个数值0(Long类型)

      本质: 延迟指定时间后,调用一次onNext()事件

    • interval()

      快速创建一个被观察者observable,每隔指定时间就发送事件,

      本质: 发送事件序列:=从0开始.无线递增1的整数序列

      // 参数说明:
              // 参数1 = 第1次延迟时间;
              // 参数2 = 间隔时间数字;
              // 参数3 = 时间单位;
      Observable.interval(3,1,TimeUnit.SECONDS)
        // 该例子发送的事件序列特点:延迟3s后发送事件,每隔1秒产生1个数字(从0开始递增1,无限个)
      
    • intervalRange()

      每隔指定时间就发送事件,可以指定发送数据的数量

      本质:类似interval() 但是可以指定发送的数据数量

      // 参数说明:
              // 参数1 = 事件序列起始点;
              // 参数2 = 事件数量;
              // 参数3 = 第1次事件延迟发送时间;
              // 参数4 = 间隔时间数字;
              // 参数5 = 时间单位
              Observable.intervalRange(3,10,2, 1, TimeUnit.SECONDS)
                //1. 从3开始,一共发送10个事件;
                // 2. 第1次延迟2s发送,之后每隔2秒产生1个数字(从0开始递增1,无限个)但是仅仅发送10次
      
    • range()

      连续发送多个事件类似于intervalRange,区别在于没有延迟

       // 参数说明:
              // 参数1 = 事件序列起始点;
              // 参数2 = 事件数量;
              // 注:若设置为负数,则会抛出异常
       Observable.range(3,10)
          // 该例子发送的事件序列特点:从3开始发送,每次发送事件递增1,一共发送10个事件
      
    • rangeLong()

      类似于range区别在于该方法支持long类型

       // 参数说明:
              // 参数1 = 事件序列起始点;
              // 参数2 = 事件数量;
              // 注:若设置为负数,则会抛出异常
       Observable.rangeLong(3L,10)
          // 该例子发送的事件序列特点:从3L开始发送,每次发送事件递增1,一共发送10个事件
      
无线轮训请求网络
 //执行interval的每隔三秒的轮询.
Observable.interval(3, TimeUnit.SECONDS).doOnNext(aLong -> {
   //开始retrofit请求
            Retrofit retrofit = new Retrofit.Builder().baseUrl("http://fy.iciba.com/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
            API api = retrofit.create(API.class);
            Observable<Model> request = api.getRange("Training request");
            request.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Model>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(Model model) {
                            model.toString();
                            Log.e(TAG, model.toString());
                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {

                        }
                    });
        }).subscribe(new Observer<Long>() {//观察者订阅事件 开始执行延迟事件
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Long aLong) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

变换操作符


作用

对整个序列中的事件/整个事件进行加工处理(变换操作),使得其转换为不同的事件/整个事件序列

类型
  • Map();

    • 作用:对被观察者(observable)发送的每个事件都通过指定函数处理,从而变换为另外一种事件 即被观察者发送的时间转换为任意类型事件

    • 引用场景:数据类型的转换

    • 具体使用: 从整形转给字符串类型

        Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
                  emitter.onNext(1);
                  emitter.onNext(2);
                  emitter.onNext(3);
              }).map(integer ->
                      "使用 Map变换操作符 将事件" + integer + "的参数从 整型" + integer + " 变换成 字符串类型" + integer)
                      .subscribe(s -> Log.e(TAG, s));
              //简化版的 subscribe(new observer<string>)
              //没有执行onCompelete和onError
      
  • FlatMap()

    作用:将被观察者发送的时间序列进行拆分&单独转换,在合并成一个新的事件序列,最后在进行发送.

    原理: 为事件序列中的每个事件都创建一个Observable对象;

    • 将对每个原始事件转换后的新事件都放入到对应observable对象;

    • 将新建的歌observable都合并到一个新建的,总的observable对象;

    • 新建的,总的observable对象,将新合并的事件序列发送给观察者observer

    • 新合并生成的事件序列是无序的,即与旧序列发送事件的序列无关

        Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
                  emitter.onNext(1);
                  emitter.onNext(2);
                  emitter.onNext(3);
              }).flatMap((Function<Integer, ObservableSource<String>>) integer -> {
                  List list = new ArrayList();
                  for (int i1 = 0; i1 < 3; i1++) {
                      list.add(i1);
                  }
                  return Observable.fromIterable(list);
              }).subscribe(s -> {
                  Log.e(TAG, s);
              });
      
  • ConcatMap()

    类似于FloatMap 但是合并后的新事件序列是有序的,顺序和原来数据一致.

      Observable.create((ObservableOnSubscribe<Integer>) emitter ->
                    emitter.onNext(1))
                    .concatMap((Function<Integer, ObservableSource<String>>) integer -> {
                        List list = new ArrayList();
                        for (int i1 = 0; i1 < 3; i1++) {
                            list.add(i1);
                        }
                        return Observable.fromIterable(list);
                    }).subscribe(s -> {
                Log.e(TAG, s);
            });
    
  • Buffer()

    定期从观察者(Observable)需要大宋的事件中获取一定数量的事件,&放入到缓存区中,最终发送

    应用场景: 缓存被观察者发送的事件,

     Observable.just(1, 2, 3, 4, 5, 6, 7).buffer(3, 1).subscribe(new Observer<List<Integer>>() {
                @Override
                public void onSubscribe(Disposable d) {
                }
                @Override
                public void onNext(List<Integer> integers) {
                    Log.e(TAG, "缓存区里的事件数量" + integers.size());
                    for (int i1 = 0; i1 < integers.size(); i1++) {
                        Log.e(TAG, "事件=:" + i1);
                    }
                }
                @Override
                public void onError(Throwable e) {
    
                }
                @Override
                public void onComplete() {
                }
            });
    

网络请求嵌套回调

功能描述: 进行多次的网络请求.
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://fy.iciba.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
        API api = retrofit.create(API.class);
        Observable<Model> range = api.getRange();
        Observable<Model> range2 = api.getRange2();
        range.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .doOnNext(model ->
                        Log.e(TAG, model.toString())
                ).observeOn(Schedulers.io()).flatMap(model -> range2)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(model -> Log.e(TAG, model.toString()), throwable ->
                        Log.e(TAG, "登录失败"+throwable.getMessage())
                );
12-17 03:04:01.434 4460-4460/com.yishion.demo_count E/RxJavaTranslation: Model{status=1, content=ContentBean{from='en-EU', to='zh-CN', out='登录个人信息', vendor='tencent', err_no=0}}
12-17 03:04:03.554 4460-4460/com.yishion.demo_count E/RxJavaTranslation: Model{status=1, content=ContentBean{from='en-EU', to='zh-CN', out='登记个人资料', vendor='tencent', err_no=0}}

组合/合并操作符

concat/concatArray (按发送顺序执行)

该类型的操作符的作用=组合多个被观察者

作用: 组合多个被观察者一起发送数据,合并后按发送顺序串口执行(concat组合最多观察者数量为4/concatArray则是大于4个)

具体使用

 Observable.concatArray(
                Observable.just(1, 89),
                Observable.just(2, 189),
                Observable.just(3, 289),
                Observable.just(4, 389),
                Observable.just(5, 478)
        ).observeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

                .subscribe(integer ->
                        Log.e(TAG, "接收到了事件" + integer)
                );
merge/mergeArry (按时间线并行执行)

作用: 组合多个被观察者一起发送数据,合并后按时间线并行执行

和concat的区别 同样是组合多个被观察者一起发送数据,单concat操作符合并后是发送顺序串口执行

具体使用:

Observable.concatArray(
                Observable.intervalRange(0,5,1,1,TimeUnit.SECONDS),
                Observable.intervalRange(6,5,1,1,TimeUnit.SECONDS),
                Observable.just(1, 89),
                Observable.just(2, 189),
                Observable.just(3, 289),
                Observable.just(4, 389),
                Observable.just(5, 478)
        ).observeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

                .subscribe(integer ->
                        Log.e(TAG, "接收到了事件" + integer)
                );
concatDelayError/mergeDelayError

若希望onError事件推迟到其他被观察者发送事件结束后才触发

 Observable.concatArrayDelayError(Observable.create(emitter -> {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
            emitter.onError(new NullPointerException());
            emitter.onNext(5);
            emitter.onComplete();
        }),Observable.just(5,8,9)).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

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

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

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

作用: 合并多个被观察者发送的事件,生成一个新的事件序列,并最终发送

 Observable<Integer> observable = Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
            emitter.onNext(1);
            Thread.sleep(1000);
            emitter.onNext(2);
            emitter.onNext(3);
            emitter.onComplete();
        }).subscribeOn(Schedulers.io());
        Observable<String> observable2 = Observable.create((ObservableOnSubscribe<String>) emitter -> {
            emitter.onNext("A");
            emitter.onNext("B");
            emitter.onNext("C");
            emitter.onNext("E");
            emitter.onComplete();
        }).subscribeOn(Schedulers.newThread());
        Observable.zip(observable, observable2, (integer, s) -> integer + s)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.e(TAG, s);
                    }

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

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete");
                    }
                });

合并数据源并且显示

  • 方法一 merge时间序列上合并

    Observable<String> observable = Observable.just("网络请求");
            Observable<String> observable1 = Observable.just("本地缓存");
            Observable.merge(observable, observable1).subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
    
                }
                @Override
                public void onNext(String s) {
                    Log.d(TAG, "数据源有: " + s);
                    result += s + "+";
                }
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "对Error事件作出响应");
                }
    
                @Override
                public void onComplete() {
                    Log.d(TAG, "onComplete" + result);
                }
            });
    
  • zip合并

    Retrofit retrofit = new Retrofit.Builder().baseUrl("http://fy.iciba.com/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
            API aip = retrofit.create(API.class);
            Observable<Model> observable = aip.getRange().subscribeOn(Schedulers.io());
            Observable<Model> observable1 = aip.getRange2().subscribeOn(Schedulers.io());
            Observable.zip(observable, observable1, (model, model2) -> model.toString() + model2.toString())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<String>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(String s) {
                            Log.d(TAG, "合并后的数据为: "+s);
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Log.d(TAG, "合并出错: "+e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
                            Log.d(TAG, "onComplete");
                        }
                    });
    //subscribeOn改变了调用前序列所运行的线程。
    //observeOn   对调用之前的序列默不关心,也不会要求之前的序列运行在指定的线程上 对之前的序列产生的结果先缓存起来,然后再在指定的线程上,推送给最终的subscriber
    

    实现三级缓存 内存->磁盘->网络

    String meayCache = null;
            String diskCache = "我是磁盘数据";
            Observable<String> observable = Observable.create(emitter -> {
                if (meayCache != null) {
                    emitter.onNext(meayCache);
                } else {
                    emitter.onComplete();
                }
            });
            Observable<String> observable1 = Observable.create(emitter -> {
                if (diskCache != null) {
                    emitter.onNext(diskCache);
                } else {
                    emitter.onComplete();
                }
            });
            Observable<String> observable2 = Observable.just("网络请求");
            Observable.concat(observable, observable1, observable2).firstElement().subscribe(s ->
                            Log.d(TAG, "数据源来自于...:" + s),
                    throwable -> Log.e(TAG, throwable.getMessage())
            );
    // 2. 通过firstElement(),从串联队列中取出并发送第1个有效事件(Next事件),即依次判断检查memory、disk、network
    // a. firstElement()取出第1个事件 = memory,即先判断内存缓存中有无数据缓存;由于memoryCache = null,即内存缓存中无数据,所以发送结束事件(视为无效事件)
    // b. firstElement()继续取出第2个事件 = disk,即判断磁盘缓存中有无数据缓存:由于diskCache ≠ null,即磁盘缓存中有数据,所以发送Next事件(有效事件)
    // c. 即firstElement()已发出第1个有效事件(disk事件),所以停止判断。
    

联合判断多个事件

//给每个edittext设置被观察者,用于发送监听 使用rxBinding
        Observable<CharSequence> nameObservable = RxTextView.textChanges(edName).skip(1);
        Observable<CharSequence> ageObservable = RxTextView.textChanges(edAge).skip(1);
        Observable<CharSequence> sexObservable = RxTextView.textChanges(edSex).skip(1);
        //通过combinelatest()合并事件&联合判断
        Observable.combineLatest(nameObservable, ageObservable, sexObservable,
                (charSequence, charSequence2, charSequence3) -> {
                    boolean isNameValid = !TextUtils.isEmpty(edName.getText());
                    boolean isAgeValid = !TextUtils.isEmpty(edAge.getText());
                    boolean isSexValid = !TextUtils.isEmpty(edSex.getText());
                    Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
                    boolean isAgeNumber = pattern.matcher(edAge.getText()).matches();
                    return isNameValid & isAgeValid & isSexValid & isAgeNumber;
                }).subscribe(aBoolean -> {
            Log.e("admin", "提交按钮是否可点击" + aBoolean);
            btnSub.setEnabled(true);
        }, throwable ->
            Log.e("admin", "出现错误" + throwable.getMessage())
        );
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值