Rxjava操作符使用

一、简介

Rxjava是基于事件流调用的方式来实现异步的库,它最大的特点就是哪怕逻辑很复杂,依然能保持简洁和优雅。异步操作很关键的一点是程序的简洁性,因为在调度过程比较复杂的情况下,异步代码经常会既难写也难被读懂。其原理是一种扩展的观察者模式。这里有四个角色:
被观察者(Observable) ==> 产生事件
观察者(Observer) ==> 接收事件,并给出响应动作
订阅(Subscribe) ==> 连接被观察者和观察者
事件(Event) ==> 被观察者 & 观察者 沟通的载体

二、基本使用

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事件作出响应");
         }
});
此外,被观察者 Observable的subscribe()具备多个重载的方法
// 表示观察者不对被观察者发送的事件作出任何响应(但被观察者还是可以继续发送事件)
public final Disposable subscribe() {}

// 表示观察者只对被观察者发送的Next事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext) {}

// 表示观察者只对被观察者发送的Next事件 & Error事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {} 
    
// 表示观察者只对被观察者发送的Next事件、Error事件 & Complete事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
    
// 表示观察者只对被观察者发送的Next事件、Error事件 、Complete事件 & onSubscribe事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, 
Action onComplete, Consumer<? super Disposable> onSubscribe) {}
    
// 表示观察者对被观察者发送的任何事件都作出响应
public final void subscribe(Observer<? super T> observer) {} 
可采用 Disposable.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事件作出响应");
     }
};

三、创建操作符

1、create
// 1. 通过creat()创建被观察者对象
Observable.create(new ObservableOnSubscribe<Integer>() {
     // 2. 在复写的subscribe()里定义需要发送的事件
      @Override
      public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
              emitter.onNext(1);
              emitter.onNext(2);
          	 emitter.onComplete();
      }  // 至此,一个被观察者对象(Observable)就创建完毕
  }).subscribe(new Observer<Integer>() {
      // 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事件作出响应");
      }
});
2、快捷创建操作符just
// 1. 创建时传入整型1、2、3
// 在创建后就会发送这些对象,相当于执行了onNext(1)、onNext(2)、onNext(3)、onComplete
 Observable.just(1, 2, 3)   
      // 2. 通过通过订阅(subscribe)连接观察者和被观察者
      // 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事件作出响应");
        }
});
3、发送一个数组fromArray()
// 1. 设置需要传入的数组
Integer[] items = { 0, 1, 2, 3, 4 };
// 2. 创建被观察者对象(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事件作出响应");
         }
});
4、发送一个集合fromIterable()
// 1. 设置一个集合
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// 2. 通过fromIterable()将集合中的对象 / 数据发送出去
Observable.fromIterable(list)
        .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、延迟创建defer()
// 第一次赋值
Integer i = 10;
// 2. 通过defer 定义被观察者对象
// 注:此时被观察者对象还没创建
Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<? extends Integer>>() {
      @Override
      public ObservableSource<? extends Integer> call() throws Exception {
          return Observable.just(i);
      }
});
// 第二次赋值
i = 15;
// 注:此时,才会调用defer()创建被观察者对象(Observable)
observable.subscribe(new Observer<Integer>() {
       @Override
       public void onSubscribe(Disposable d) {
           Log.d(TAG, "开始采用subscribe连接");
       }

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

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

       @Override
       public void onComplete() {
           Log.d(TAG, "对Complete事件作出响应");
       }
});
6、延迟发送timer()
// 延迟2s后,发送一个long=0类型数值
// 注:timer操作符默认运行在一个新线程上
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事件作出响应");
        }
});
7、定时发送事件interval
// 参数说明:
// 参数1 = 第1次延迟时间;
// 参数2 = 间隔时间数字;
// 参数3 = 时间单位;
Observable.interval(3,1,TimeUnit.SECONDS)
       // 该例子发送的事件序列特点:延迟3s后发送事件,每隔1秒产生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事件作出响应");
           }
});
8、定时发送事件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连接");
          }

          @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事件作出响应");
          }
});
9、无延迟发送事件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事件作出响应");
         }
});

四、变换操作符

1、map变换操作符

对被观察者发送的每1个事件都通过 指定的函数处理,从而变换成另外一种事件

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);
        }
});
2、flatMap变换操作符

将被观察者发送的事件序列进行拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送

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事件
            }
            // 所有事件最终合并成Observable后才会发送给观察者。
            return Observable.fromIterable(list);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.d(TAG, s);
        }
});

// 结果如下:

我是事件3拆分后的子事件0
我是事件2拆分后的子事件0
我是事件2拆分后的子事件1
我是事件2拆分后的子事件2
我是事件3拆分后的子事件1
我是事件3拆分后的子事件2
我是事件1拆分后的子事件0
我是事件1拆分后的子事件1
我是事件1拆分后的子事件2
3、contactMap变换操作符

和flatMap一样,只是contactMap保证了输入和输出的顺序。如果使用了contactMap,那么顺序如下:

我是事件1拆分后的子事件0
我是事件1拆分后的子事件1
我是事件1拆分后的子事件2
我是事件2拆分后的子事件0
我是事件2拆分后的子事件1
我是事件2拆分后的子事件2
我是事件3拆分后的子事件0
我是事件3拆分后的子事件1
我是事件3拆分后的子事件2
4、Buffer变换操作符

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

// 被观察者 需要发送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事件作出响应");
          }
});

Buffer变换过程

五、组合/并发操作符

1、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事件作出响应");
          }
});

结果如下:

接收到了事件1
接收到了事件2
接收到了事件3
接收到了事件4
接收到了事件5
接收到了事件6
接收到了事件7
接收到了事件8
接收到了事件9
接收到了事件10
接收到了事件11
接收到了事件12
对Complete事件作出响应
2、concatArray

和1中的concat没有区别,仅仅只是concatArray可以发送大于4个的事件流

3、merge

组合多个被观察者一起发送数据,合并后按时间线并行执行
区别上述concat()操作符:同样是组合多个被观察者一起发送数据,但concat()操作符合并后是按发送顺序串行执行

Observable.merge(
	  // 从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
      Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS),
      // 从2开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
      Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS)) 
        .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事件作出响应");
          }
});

结果如下:

接收到了事件0
接收到了事件2
接收到了事件1
接收到了事件3
接收到了事件2
接收到了事件4
4、zip

合并 多个被观察者(Observable)发送的事件,生成一个新的事件序列(即组合过后的事件序列),并最终发送。
事件组合方式 = 严格按照原先事件序列 进行对位合并
最终合并的事件数量 = 多个被观察者(Observable)中数量最少的数量

Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
          @Override
          public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
              emitter.onNext(1);
              emitter.onNext(2);
              emitter.onNext(3);
              emitter.onComplete();
          }
}).subscribeOn(Schedulers.io()); // 设置被观察者1在工作线程1中工作

Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
         @Override
         public void subscribe(ObservableEmitter<String> emitter) throws Exception {
             emitter.onNext("A");
             Thread.sleep(1000);

             emitter.onNext("B");
             Thread.sleep(1000);

             emitter.onNext("C");
             Thread.sleep(1000);

             emitter.onNext("D");
             Thread.sleep(1000);

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

// 注:创建BiFunction对象传入的第3个参数 = 合并后数据的数据类型
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
         @Override
         public String apply(Integer integer, String string) throws Exception {
             return "@@@" + integer + string + "@@@";
         }
     }).subscribe(new Observer<String>() {
         @Override
         public void onSubscribe(Disposable d) {
             Log.d(TAG, "onSubscribe");
         }

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

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

         @Override
         public void onComplete() {
             Log.d(TAG, "onComplete");
         }
});
D/zhangbh: onSubscribe
D/zhangbh: 最终接收到的事件 =  @@@1A@@@
D/zhangbh: 最终接收到的事件 =  @@@2B@@@
D/zhangbh: 最终接收到的事件 =  @@@3C@@@
D/zhangbh: onComplete

ZIP操作过程

六、线程切换/调度

Schedulers.immediate() ==> 当前线程 = 不指定线程(默认)
AndroidSchedulers.mainThread() ==>Android主线程
Schedulers.newThread() ==> 常规新线程 (耗时等操作)
Schedulers.io() ==> io操作线程、网络请求、读写文件等io密集型操作
Schedulers.computation() ==> CPU计算操作线程(大量计算操作)

1、subscribeOn,指定被观察者发送事件的线程
Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                // 执行在io线程
                Log.i(TAG, "==create==" + Thread.currentThread().getName());
                e.onNext(1);
            }
            // 指定被观察者执行在io线程
        }).subscribeOn(Schedulers.io())
                // 这个指定无效,subscribeOn只有第一个设置的线程有效
                .subscribeOn(Schedulers.newThread())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) throws Exception {
                        // 执行在主线程
                        Log.i(TAG, "==doOnSubscribe==" + Thread.currentThread().getName());
                    }
                    // 指定doOnSubscribe执行在主线程
                }).subscribeOn(AndroidSchedulers.mainThread())
                .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事件作出响应");
                    }
                });

订阅成功后,先执行doOnSubscribe的回调,这个时候就看有没有使用subscribeOn指定其执行线程,如果没有,那么就默认使用当前订阅所处的线程。如果有,像上例子,那么就使用主线程执行这个回调。接着需要执行被观察者的发送,依然看有没有通过subscribeOn指定线程,如果没有,这个时候会使用doOnSubscribe后的subscribeOn设置的线程。如果有,那当然就用自己设置的。此外,多次设置subscribeOn,只有第一次有效。

2、observeOn,指定观察者 接收 & 响应事件的线程
Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                // 执行在io线程
                Log.i(TAG, "==create==" + Thread.currentThread().getName());
                e.onNext(1);
            }
            // 指定被观察者Observable执行在io线程
        }).subscribeOn(Schedulers.io())
                // 指定观察者doOnNext执行在newThread
                .observeOn(Schedulers.newThread())
                // 指定观察者doOnNext执行在io
                .observeOn(Schedulers.io())
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        // 由于observeOn多次切换都有效,所以最终这里会执行在io线程
                        Log.i(TAG, "==doOnNext==" + Thread.currentThread().getName());
                    }
                    // 指定观察者Observer执行在主线程
                }).observeOn(AndroidSchedulers.mainThread())
                .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相关操作符

1、doOnNext()

发送next事件时,最晚在观察者执行onNext前调用,属于观察者,所以使用observeOn切换线程。

2、doAfterNext()

发送next事件时,在观察者执行onNext后调用,属于观察者,所以使用observeOn切换线程。

3、doOnError()

发送error事件时,最晚在观察者执行onError前调用,属于观察者,所以使用observeOn切换线程。

4、doOnComplete()

发送complete事件时,最晚在观察者执行onComplete前调用,属于观察者,所以使用observeOn切换线程。

5、doOnEach()

发送任何事件,都会调用此方法,属于观察者,所以使用observeOn切换线程。

6、doFinally()

所有事件的最后执行,比观察者的执行onComplete还晚,属于观察者,所以使用observeOn切换线程。

7、doOnSubscribe()

观察者订阅的时候被调用,优先于被观察者的发送,属于被观察者,所以使用subscribeOn切换线程。

8、doOnDispose()

观察者取消订阅时调用,属于观察者,所以使用observeOn切换线程。

八、错误处理

1、onErrorReturn

遇到错误时,发送1个特殊事件 & 正常终止

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事件作出响应
2、retry

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

九、过滤操作符

1、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事件作出响应");
            }
        });
2、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事件作出响应");
            }
        });
3、takeLast

和take差不多,指定观察者只能接收到被观察者发送的最后几个事件

4、throttleFirst和throttleLast

在某段时间内,只发送该段时间内第1次事件 / 最后1次事件
throttle

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事件作出响应");
                    }
                });
开始采用subscribe连接
接收到了事件1
接收到了事件4
接收到了事件7
对Complete事件作出响应
5、throttleWithTimeout

发送数据事件时,若2次发送事件的间隔<指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才会发送后一次的数据。

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事件作出响应");
                    }
                });
接收到了事件2
接收到了事件3
接收到了事件6
对Complete事件作出响应

十、布尔操作符

1、all

判断发送的每项数据是否都满足设置的函数条件,若都满足,才能往下走。

2、takeWhile

判断某项数据是否满足设置的函数条件,满足的项才能往下走。

3、skipWhile

当某项==false时,才能往下走,和takeWhile相反。

4、takeUntil
// 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() {
            }
        });
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值