全面学习RxJava/RxAndroid/AutoDispose/RxBinding/RxBus

6,784 阅读37分钟

首先:

  • RXJava建议先掌握Lambda, 否则要定义很多泛型. 并且代码量冗余.
  • RxJava分为三部分, Observable 被观察者 和 Observer 观察者 以及操作符.
  • Reactive流式编程是微软提出来的概念, 由Netfix公司实现的架构.
  • RxJava是针对Java语言, Android和JavaEE都可以使用, 但是目前主要是Android在使用.
  • 操作符(或者直接叫方法)有很多变形(或者说方法的重载)

优点:

  • 对于多线程任务的异步处理非常强大和方便
  • 某些自己实现很复杂的功能RxJava都提供好了

我平时项目开发必备框架

  1. Android上最强网络请求 Net
  2. Android上最强列表(包含StateLayout) BRV
  3. Android最强缺省页 StateLayout
  4. JSON和长文本日志打印工具 LogCat
  5. 支持异步和全局自定义的吐司工具 Tooltip
  6. 开发调试窗口工具 DebugKit
  7. 一行代码创建透明状态栏 StatusBar

官方网站:

  • ReactiveX

    ReactiveX支持多种语言, RxJava只是其中一种而已(还例如RxPHP, RxSwift, RxKotlin).
    
  • RxJava

  • RxKotlin

针对Android的扩展

  • RxAndroid

    主要是增加了Android中的主线程(AndroidSchedulers)
    
  • RxBinding

    该框架比较繁琐臃肿, 建议自己实现

  • AutoDispose

    我的开源项目, 跟随生命周期自动解除观察者订阅. 并且可以设置生命周期. 比Uber的开源项目AutoDispose更简单
    
  • RxBus

    我的开源项目, 替代EventBus等事件框架, 具体看README
    
    支持三种类型事件
    
    - 标签
    - 事件
    - 标签 + 事件
    
  • Net

    我的开源项目, 全自动的网络请求框架, 基于Kalle(Nohttp2.0版本)的作者严振杰的库进行再次封装, 增加RxJava/Kotlin等新特性. 
    具体看README
    

文档

RxJavaDoc

RxJava中文翻译文档

基本使用

调度器

public final Observable<T> subscribeOn(Scheduler scheduler)

public final Observable<T> observeOn(Scheduler scheduler)

AndroidScheduler是RxAndroid添加的调度器, 主要增加了主线程.

  1. 被观察者默认在创建实例的当前线程下, 观察者(操作符)跟随被观察者线程;
  2. subscribeOn决定被观察者的线程(只有第一次指定线程有效), 某些被观察者拥有默认线程就无法变更(例如interval默认在computation线程下)
  3. observeOn决定以下的观察者线程(包括操作符) (可以多次变更线程), 包括observerOn以下的无默认调度器的操作符回调函数的执行线程;

操作符

  • 不能指定Scheduler的操作符都是跟随被观察者的线程, 可以通过subscribeOn来控制被观察者发射事件的线程
  • 如果操作符拥有默认的线程调度器将无法通过subscribeOn来控制(但是一般有重载方法可以在参数中控制)

调度器类型

Schedulers.computation( )	
用于计算任务,如事件循环或和回调处理,不要用于io操作, 线程数等于处理器的数量

Schedulers.from(executor)	
使用指定的Executor作为调度器

Schedulers.io( )
用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用

Schedulers.newThread( )
为每个任务创建一个新的线程

Schedulers.trampoline( )
在当前线程执行任务

Schedulers.single()	
所有使用该调度器的都始终处于同一个线程,且任务以先进先出的顺序被执行.

批量解除订阅关系

CompositeDisposable

示例:

CompositeDisposable compositeDisposable=new CompositeDisposable();

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onComplete();或者 emitter.onError(new Throwable("O__O "));
            }
        }).subscribe(new Observer<Integer>() {
            private Disposable mDisposable;
            @Override
            public void onSubscribe(Disposable d) {
               // 订阅  
                mDisposable = d;
               // 添加到容器中 
                compositeDisposable.add(d);
            }
            @Override
            public void onNext(Integer value) {
               // 判断mDisposable.isDisposed() 如果解除了则不需要处理
            }
            @Override
            public void onError(Throwable e) {
            }
            @Override
            public void onComplete() {
            }
        });
        // 解除所有订阅者
        compositeDisposable.clear();

需要强调的是Observable只有存在订阅者的时候才会发送事件, 如果取消了订阅者并不会发送任何事件, 不用担心内存泄漏等问题.

周期函数

doOn**()这一系列方法都是可以在观察者回调之前执行操作

public final Flowable<T> doOnDispose(Action onCancel)

    public final Flowable<T> doOnComplete(Action onComplete)

    public final Flowable<T> doOnEach(Consumer<? super Notification<T>> onNotification)
    // 发送任何事件都会触发回调(包括onError onComplete)

    public final Flowable<T> doOnEach(org.reactivestreams.Subscriber<? super T> subscriber)

    public final Flowable<T> doOnError(Consumer<? super java.lang.Throwable> onError)

    public final Flowable<T> doOnLifecycle(Consumer<? super org.reactivestreams.Subscription> onSubscribe,
                                           LongConsumer onRequest,
                                           Action onCancel)


    public final Flowable<T> doOnNext(Consumer<? super T> onNext)

    public final Flowable<T> doOnRequest(LongConsumer onRequest)
    // 该方法用于跟踪背压, 常常用于调试, 故Observable没有该方法

    public final Flowable<T> doOnSubscribe(Consumer<? super org.reactivestreams.Subscription> onSubscribe)
    // 在订阅被观察者前回调

    public final Flowable<T> doOnTerminate(Action onTerminate)
    // 该回调会在onComplete和onError方法前回调, 无论是异常还是完成

Notification

因为doOnEach回调会在所有事件都触发, 所以Notification包含了所有事件的信息

java.lang.Throwable	getError()
// 如果触发的事件是onError则会返回异常信息, 否则null

T	getValue()
// 如果触发的事件是onNext则会返回该值, 否则返回null

boolean	isOnComplete()

boolean	isOnError()

boolean	isOnNext()

// Notification提供静态方法直接构成出三种事件的实例对象
static <T> Notification<T>	createOnComplete()

static <T> Notification<T>	createOnError(java.lang.Throwable error)

static <T> Notification<T>	createOnNext(T value)

生命周期拦截

Lift

Observable.just(1).lift(ObservableOperator<String, Int> {

  object :DisposableObserver<Int>(){
    override fun onComplete() {
    }

    override fun onNext(t: Int) {
      Log.d("日志", "(MainActivity.kt:43):onNext 拦截   t = $t")
    }

    override fun onError(e: Throwable) {
    }
  }

}).subscribe(object : Observer<String?> {
  override fun onComplete() {
  }

  override fun onSubscribe(d: Disposable) {
  }

  override fun onNext(t: String) {
    Log.d("日志", "(MainActivity.kt:59):onNext 最终  t = $t")
  }

  override fun onError(e: Throwable) {
  }
})

Compose

public final <R> Observable<R> compose(ObservableTransformer<? super T,? extends R> composer)

compose属于流转换操作符, 和FlatMap不同的是Compose是针对整个流执行的转换, 而FlatMap针对的是数据转换.

故数据有多少则Flatmap执行多少次, 而Compose只会执行一次.

Observable.just(1).compose(object : ObservableTransformer<Int, String> {

    override fun apply(upstream: Observable<Int>): ObservableSource<String> {
    }
})

###AS

Observable.just(1).`as`(object : ObservableConverter<Int, ObservableSource<String>> {
    override fun apply(upstream: Observable<Int>): ObservableSource<String> {
    }
})
  • compose属于数据流的转换, as可以单纯是数据转换.

创建被观察者

Create

用于创造自定义Observable

public static <T> Observable<T> create(ObservableOnSubscribe<T> source)

ObservableOnSubscribe中只有一个方法

void subscribe(ObservableEmitter<T> e)
               throws java.lang.Exception

ObservableEmitter 译为发射器. 可以通过三种方法发送事件

void	onComplete()

void	onError(java.lang.Throwable error)

void	onNext(T value)

Tip:

  • onError()onComplete()不能同时使用
  • onError()不能多次使用, onComplete()可以
  • 发射事件或者异常等之前请先判断是否观察者已经取消订阅, 否则会抛出异常

其他方法:

void setCancellable(Cancellable c)
// 设置一个取消事件监听器

void setDisposable(Disposable d)

boolean	isDisposed()

Just

通过直接传入N个参数来批量发送事件(最多九个参数)

static <T> Observable<T>	just(T item) 

全部事件发送完毕后会回调onComplete方法

FromArray

通过传入数组或者集合来发送事件

static <T> Observable<T>	fromArray(T... items)

FromIterable

Iterable是可遍历集合的根接口, 可以通过发送集合;

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");

Flowable.fromIterable(list).subscribe(
        s -> Log.i("tag", s)
);

更多的方法

public static <T> Observable<T> fromArray(T... items)

public static <T> Observable<T> fromCallable(java.util.concurrent.Callable<? extends T> supplier)

public static <T> Observable<T> fromFuture(java.util.concurrent.Future<? extends T> future)

public static <T> Observable<T> fromFuture(java.util.concurrent.Future<? extends T> future,
                                                                  long timeout,
                                                                  java.util.concurrent.TimeUnit unit)

Defer

只能够在回调函数中创建被观察者

public static <T> Observable<T> defer(java.util.concurrent.Callable<? extends ObservableSource<? extends T>> supplier)

StartWith

在已经创建的事件前面再添加事件

public final Observable<T> startWith(T item)

public final Observable<T> startWithArray(T... items)

立即结束流

Empty

不发送任何事件给观察者, 立即回调onComplete()

Flowable.empty().subscribe(
        obj -> Log.i("tag", "next" + obj.toString()),
        e -> Log.i("tag", "error"),
        () -> Log.i("tag", "complete"));

Never

不发送任何事件给观察者, 并且不执行任何方法(例如OnComplete)

Error

不发送任何事件, 但是会直接执行onError()

轮循器

Interval

定时控制间隔发送事件. 默认在计算线程(ComputationScheduler), 可以指定线程.

只能控制间隔时间

public static Observable<java.lang.Long> interval(long period,
                                                  java.util.concurrent.TimeUnit unit)

public static Observable<java.lang.Long> interval(long initialDelay, // 第一次的延迟时间
                                                    long period, // 间隔时间
                                                    java.util.concurrent.TimeUnit unit) // 时间单位

IntervalRange

更加精确的范围内发送计时器事件, 默认在计算线程(ComputationScheduler), 可以指定线程.

可以控制发送次数

public static Observable<java.lang.Long> intervalRange(long start,  // 开始数字
                                                       long count, // 总共次数
                                                       long initialDelay, // 初始间隔时间
                                                       long period, // 后面每次间隔时间
                                                       java.util.concurrent.TimeUnit unit) // 时间单位

Timer

等同于interval

  • 指定间隔时间
  • 时间单位
  • 指定线程 (computationScheduler)
public static Observable<java.lang.Long> timer(long delay, // 间隔时间
                                               java.util.concurrent.TimeUnit unit) // 时间单位

TimerInterval

记录轮循器的信息

  • 时间间隔
  • 时间单位
  • 指定线程
public final Observable<Timed<T>> timeInterval()

// 时间间隔设置固定单位
public final Observable<Timed<T>> timeInterval(TimeUnit unit)

输出示例:

// 无参默认单位为毫秒
Timed[time=1003, unit=MILLISECONDS, value=12]

// 设置单位为秒
Timed[time=1, unit=SECONDS, value=40]

Range

观察者收到范围内数字, 没有默认在特定的线程执行.

  • 开始数字
  • 数字范围
// 发送int事件类型
public static Observable<java.lang.Integer> range(int start, // 开始
                                                  int count) // 结束

// 发送long的事件类型
public static Observable<java.lang.Long> rangeLong(long start,
                                                     long count)

Repeat

重复发送事件

  • 无限循环
  • 循环次数
  • 结束循环时间
  • 结束循环条件
public final Observable<T> repeat()
// 无限循环

public final Observable<T> repeat(long times)
// 设置循环次数

public final Observable<T> repeatUntil(BooleanSupplier stop)
// 设置循环结束条件

public final Observable<T> repeatWhen(Function<? super Observable<java.lang.Object>,
                                     ? extends ObservableSource<?>> handler)
// 添加一个被观察者作为重新发送事件的条件

示例

        io.reactivex.Observable.just(1)
                .repeatUntil(
                        new BooleanSupplier() {
                            /**
                             * @return 返回true表示结束循环
                             * @throws Exception
                             */
                            @Override
                            public boolean getAsBoolean() throws Exception {
                                return true;
                            }
                        })
                .subscribe(System.out::println);

RepeatWhen

如果回调函数中的被观察者发送onComplete和onError事件不会进入重复事件

但是如果发送onNext事件就会导致重复发送

Observable.intervalRange(0, 5, 1, 1, TimeUnit.SECONDS, TrampolineScheduler.instance())
    .repeatWhen(
    new Function<Observable<Object>, ObservableSource<?>>() {
        @Override
        public ObservableSource<?> apply(Observable<Object> objectObservable)
            throws Exception {

            // 源被观察者结束后(onComplete)等待五秒再次重新发送
            return Observable.interval(5, TimeUnit.SECONDS);
        }
    })
    .subscribe(
    new Consumer<Long>() {
        @Override
        public void accept(Long aLong) throws Exception {
            // do something
        }
    });

多观察者创建

Concat

将多个被观察者连接起来按照顺序发送

ConcatArrayConcat操作符其实都一样, 只不过可以接受数组而已

Merge

将多个被观察者合并, 遵守时间顺序(不遵守参数添加顺序)

public static <T> Observable<T> mergeArray(int maxConcurrency,
                                           int bufferSize,
                                           ObservableSource<? extends T>... sources)

Zip

可以将多个发射器发送的事件对应发送顺序组合成一个然后统一一次接收事件, 遵守两两合并的原则.

如果存在异步情况, 将会等待需要合并的两个事件同时执行完毕后再发送给观察者;

  • 遵守订阅顺序
public static <T,R> Observable<R> zip(ObservableSource<? extends ObservableSource<? extends T>> sources,
                                      Function<? super java.lang.Object[],? extends R> zipper)

示例:

Observable.zip(getStringObservable(), getIntegerObservable(),
               new BiFunction<String, Integer, String>() {
                 @Override public String apply(@NonNull String s, @NonNull Integer integer)
                   throws Exception {
                   // 在这里将两个发射器的事件合并然后统一发送
                   return s + integer;
                 }
               }).subscribe(new Consumer<String>() {
  @Override public void accept(@NonNull String s) throws Exception {
    // 这里只会接受到apply的返回值
  }
});

ZipWith

将传入的被观察者和源被观察者对应组合(Zip)该方法属于非静态方法

    Observable.just(1).zipWith(Observable.just(2), new BiFunction<Integer, Integer, String>() {
        @Override
        public String apply(Integer integer, Integer integer2) throws Exception {
            System.out.println("integer = [" + integer + "], integer2 = [" + integer2 + "]");
            return integer + "" + integer2;
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            // 结果: s = [12]
            System.out.println("s = [" + s + "]");
        }
    });

CombineLast

最后一个被观察者的所有事件依次前面的所有被观察者的最后事件依次合并, 然后观察者依次收到合并后的事件

  • 遵守订阅观察者顺序
public static <T1,T2,T3,R> Observable<R> combineLatest(ObservableSource<? extends T1> source1,
                                                       ObservableSource<? extends T2> source2,
                                                       Function3<? super T1,? super T2,? super T3,? extends R> combiner)

示例结果:

最后一个被观察者和之前的所有的被观察者的最后一个事件同时被接收到

s = [轮循器一10轮循器二10轮循器三1]
s = [轮循器一10轮循器二10轮循器三2]
s = [轮循器一10轮循器二10轮循器三3]
s = [轮循器一10轮循器二10轮循器三4]
s = [轮循器一10轮循器二10轮循器三5]
s = [轮循器一10轮循器二10轮循器三6]
s = [轮循器一10轮循器二10轮循器三7]
s = [轮循器一10轮循器二10轮循器三8]
s = [轮循器一10轮循器二10轮循器三9]
s = [轮循器一10轮循器二10轮循器三10]

该函数属于第一个被观察者的所有事件依次和后面的所有被观察者的最新事件合并发送给观察者

public final <R> Observable<R> withLatestFrom(ObservableSource<?>[] others,
                                              Function<? super java.lang.Object[],R> combiner)

变化操作符

FlatMap

将事件拦截然后转成被观察者再次发送

交错顺序, 即发射器发送事件的时候可能是异步或者延迟的.

public final <R> Observable<R> flatMap(Function<? super T,? extends ObservableSource<? extends R>> mapper)


// onNext/onError/onComplete 分别回调
public final <R> Observable<R> flatMap(Function<? super T,? extends ObservableSource<? extends R>> onNextMapper,
                                                               Function<? super java.lang.Throwable,? extends ObservableSource<? extends R>> onErrorMapper,
                                                               java.util.concurrent.Callable<? extends ObservableSource<? extends R>> onCompleteSupplier)

    
public final <U,R> Observable<R> flatMap(Function<? super T,? extends ObservableSource<? extends U>> mapper,
                                                                 BiFunction<? super T,? super U,? extends R> resultSelector)

FlatMapIterable

public final <U> Observable<U> flatMapIterable(Function<? super T,? extends java.lang.Iterable<? extends U>> mapper)
// 就是转成集合类型被观察者接收到

重载方法将可迭代对象最终又转换成单个对象

public final <U,V> Observable<V> flatMapIterable(
    Function<? super T,? extends java.lang.Iterable<? extends U>> mapper,
    BiFunction<? super T,? super U,? extends V> resultSelector)

示例

 Observable.just(1, 2, 3, 4, 5).flatMapIterable(new Function<Integer, Iterable<String>>() {
      @Override public Iterable<String> apply(Integer integer) throws Exception {
        Log.d("日志",
            "(MainActivity.java:32) ___ " + "apply() called with: integer = [" + integer + "]");
        
        // iterable属于所有集合的根接口
        ArrayList<String> strings = new ArrayList<>();
        strings.add(integer.toString() + "集合中");
        return strings;
      }
    }, new BiFunction<Integer, Object, String>() {

      /**
       * 得到一个最终被观察者接受的事件
       * @param t1 发射器的事件
       * @param t2 被添加到集合中对象
       * @return 最终被观察者接受的事件
       * @throws Exception 如果返回null将抛出异常
       */
      @Override public String apply(Integer integer, Object o) throws Exception {
        Log.d("日志", "(MainActivity.java:39) ___ "
            + "apply() called with: integer = ["
            + integer
            + "], o = ["
            + o
            + "]");
        // 如果返回null则会抛出异常进入onError
        return "吴彦祖";
      }
    }).subscribe(new Observer<String>() {
      @Override public void onSubscribe(Disposable d) {
        Log.i("日志", "(MainActivity.java:49) ___ onSubscribe");
      }

      @Override public void onNext(String s) {
        Log.d("日志", "(MainActivity.java:53) ___ " + "onNext() called with: s = [" + s + "]");
      }

      @Override public void onError(Throwable e) {
        Log.i("日志", "(MainActivity.java:57) ___ onError");
      }

      @Override public void onComplete() {
        Log.i("日志", "(MainActivity.java:61) ___ onComplete");
      }
    });

FatMapCompletable

只能接受到onComplete回调

public final Completable flatMapCompletable(Function<? super T,? extends CompletableSource> mapper)

    public final Completable flatMapCompletable(Function<? super T,? extends CompletableSource> mapper,
                                                boolean delayErrors)

FlatMapMaybe

public final <R> Observable<R> flatMapMaybe(Function<? super T,? extends MaybeSource<? extends R>> mapper);


public final <R> Observable<R> flatMapMaybe(Function<? super T,? extends MaybeSource<? extends R>> mapper,
                                            boolean delayErrors)

FlatMapSingle

单一接受者

public final <R> Observable<R> flatMapSingle(Function<? super T,? extends SingleSource<? extends R>> mapper)


public final <R> Observable<R> flatMapSingle(Function<? super T,? extends SingleSource<? extends R>> mapper,
                                                 boolean delayErrors)

ConcatMap

和FlatMap的区别是保证顺序发射(不存在交错顺序), 内部使用Concat实现;

例如: 两个异步的被观察者无论如何都会按照你参数添加的顺序发送事件

public final <R> Flowable<R> concatMap(Function<? super T,? extends org.reactivestreams.Publisher<? extends R>> mapper)

public final <R> Flowable<R> concatMap(Function<? super T,? extends org.reactivestreams.Publisher<? extends R>> mapper,
                                           int prefetch)

ConcatMapDelayError

延迟异常抛出到所有事件发送完毕后

public final <R> Flowable<R> concatMapDelayError(Function<? super T,? extends org.reactivestreams.Publisher<? extends R>> mapper)

public final <R> Flowable<R> concatMapDelayError(Function<? super T,? extends org.reactivestreams.Publisher<? extends R>> mapper,
                                                     int prefetch,
                                                     boolean tillTheEnd)

ConcatMapEager

将所有被观察者的事件全部添加到一个被观察者上, 然后一次性发送;

public final <R> Observable<R> concatMapEager(Function<? super T,? extends ObservableSource<? extends R>> mapper)

事件变化

Map

将类型转换

public final <R> Flowable<R> map(Function<? super T,? extends R> mapper)

SwitchMap

每次源被观察者发送数据的时候都会向观察者发送一个新的被观察者, 但是如果有延迟操作就只会发送最后一个源被观察者创建的新被观察者;

在RxJava2之前SwitchMap叫做FlatMapLatest, 这样是否更加容易理解

public final <R> Observable<R> switchMap(Function<? super T,? extends ObservableSource<? extends R>> mapper)

示例

    Observable.just(1, 2, 3)
            .switchMap(new Function<Integer, ObservableSource<?>>() {
              @Override
              public ObservableSource<Long> apply(Integer integer) throws Exception {
                return interval1;
              }
            })
            .subscribe(ele -> Log.d("日志", "(MainActivity.java:39) ___ Result = " + ele));

截取事件

Buffer

创建一个List集合存储事件发送给观察者

  • 数量
  • 跨度
  • 时间
public final Observable<java.util.List<T>> buffer(int count) // 向List中添加事件数量

public final Observable<java.util.List<T>> buffer(int count,
                                                  int skip) // 分段事件跨度

例如: {1.2.3.4.5} count = 3, skip = 2.

接收到的事件就为 {1,2,3} {3,4,5} {5}

public final <B> Observable<java.util.List<T>> buffer(java.util.concurrent.Callable<? extends ObservableSource<B>> boundarySupplier)
// 在回调接口中boundarySupplier封装成集合Collection


// 缓存一定时间内的事件添加到集合中
public final Observable<java.util.List<T>> buffer(long timespan,
                                                  long timeskip,
                                      			java.util.concurrent.TimeUnit unit)

Window

创建一个被观察者存储事件发送给观察者, 和Buffer的区别是返回的不是集合而是观察者, 该观察者包含跨度内的事件.

分时间

public final Observable<Observable<T>> window(long timespan,
                                              java.util.concurrent.TimeUnit unit)
// 按照时间跨度分组

public final Observable<Observable<T>> window(long timespan,
                                                  java.util.concurrent.TimeUnit unit,
                                                  long count)
    // 按照时间跨度内的数量分组 (规定事件内只能添加规定数量的事件到被观察者内)

public final Observable<Observable<T>> window(long timespan,
                                                  long timeskip,
                                                  java.util.concurrent.TimeUnit unit)
    // 按照时间跨度分组

public final Observable<Observable<T>> window(long timespan,
                                                  java.util.concurrent.TimeUnit unit,
                                                  long count,
                                                  boolean restart)

分观察者发送

public final Observable<Observable<T>> window(long count)
// 按照数量分组

public final Observable<Observable<T>> window(long count,
                                              long skip)
// 按照跨度分组

示例

    Observable.just(1, 2, 3, 4).window(3).subscribe(new Consumer<Observable<Integer>>() {
      @Override public void accept(Observable<Integer> integerObservable) throws Exception {
        Log.i("日志", "(MainActivity.java:19) ___ 观察者");
        
        integerObservable.subscribe(new Consumer<Integer>() {
          @Override public void accept(Integer integer) throws Exception {
            Log.i("日志", "(MainActivity.java:23) ___ 接受到事件");
          }
        });

      }
    });
public final <B> Observable<Observable<T>> window(Callable<? extends ObservableSource<B>> boundary)
// 参数观察者每次发送事件就会导致截取
    
public final <U,V> Observable<Observable<T>> window(ObservableSource<U> openingIndicator,
                               Function<? super U,? extends ObservableSource<V>> closingIndicator)

public final <U,V> Observable<Observable<T>> window(ObservableSource<U> openingIndicator,
                                      Function<? super U,? extends ObservableSource<V>> closingIndicator,
                                                     int bufferSize)
// openingIndicator发送事件为开始截取, closingIndicator发送事件则停止截取, 一段一段的发送给观察者

GroupBy

根据key将Observable被观察者的事件分组变更为GroupedObservable, 该类继承自Observable, 但是新增一个方法

getKey()可以获取回调中返回对象key;

// 每次事件发送都会在参数回调中返回一个key, 如果key相等则会分成一组
public final <K> Observable<GroupedObservable<K,T>> groupBy(Function<? super T,? extends K> keySelector)



// 分组然后再次发送事件
public final <K,V> Observable<GroupedObservable<K,V>> groupBy(Function<? super T,? extends K> keySelector,
                                                   			Function<? super T,? extends V> valueSelector)

ToList

将事件转成集合一次接受; 但是主要要求被观察者的事件类型统一

public final Single<java.util.List<T>> toList()

public final Single<java.util.List<T>> toList(int capacityHint)
// 集合初始化空间

public final <U extends java.util.Collection<? super T>> Single<U> toList(java.util.concurrent.Callable<U> collectionSupplier)

去除重复事件

Distinct

相同事件去重

public final Flowable<T> distinct()
// 去除所有重复的事件

public final <K> Observable<T> distinct(Function<? super T,K> keySelector)
// 在回调内返回一个泛型值, 然后比较该泛型值来判断是否属于重复

public final <K> Observable<T> distinct(Function<? super T,K> keySelector,
                                                                java.util.concurrent.Callable<? extends java.util.Collection<? super K>> collectionSupplier)

示例:

    /*演示只取两个偶数*/
    Observable.just(1, 2, 3, 4, 5, 6).distinct(new Function<Integer, String>() {
      /**
       * 该方法每次发送事件都会回调
       * @throws Exception
       */
      @Override public String apply(Integer integer) throws Exception {
        return integer % 2 == 0 ? "偶数" : "奇数";
      }
    }).subscribe(new Consumer<Integer>() {
      @Override public void accept(Integer integer) throws Exception {
        Log.d("日志",
            "(MainActivity.java:34) ___ " + "accept() called with: integer = [" + integer + "]");
      }
    });

DistinctUntilChanged

去除临近的重复事件

public final Flowable<T> distinctUntilChanged()
// 只会去除邻近的重复事件

public final Observable<T> distinctUntilChanged(BiPredicate<? super T,? super T> comparer)
// 该回调会每次返回邻近的两个事件, 然后你自己在回调内比较两个值是否算重复, 返回布尔类型

public final <K> Observable<T> distinctUntilChanged(Function<? super T,K> keySelector)
// 在回调内返回一个泛型值, 然后比较该泛型值来判断是否属于重复

示例:

    Observable.just(1, 2, 2, 4, 5, 6).distinctUntilChanged(new BiPredicate<Integer, Integer>() {
      @Override public boolean test(Integer integer, Integer integer2) throws Exception {
        
        return integer.equals(integer2);
      }
    }).subscribe(new Consumer<Integer>() {
      @Override public void accept(Integer integer) throws Exception {
        Log.d("日志",
            "(MainActivity.java:34) ___ " + "accept() called with: integer = [" + integer + "]");
      }
    });

只发送指定数据

Element

只发送指定位置(索引)的事件

public final Maybe<T> elementAt(long index) // 索引

public final Single<T> elementAt(long index,
                                 T defaultItem) // 索引越界后发送事件

public final Maybe<T> firstElement()
// 只发送第一个

public final Maybe<T> lastElement()

public final Completable ignoreElements()
// 忽略全部事件

public final Single<T> elementAtOrError(long index)
// 如果事件为空, 则会抛出异常

Debounce

发送事件后的一定时间内再次发送的事件都会被舍弃, 并且重新开始计时.

这个场景常用语搜索输入框的自动提示: 你连续输入文字会不断地发送事件,即会导致时间不断地被重置始终无法成功发送事件. 只有你在停止输入后才会成功发送事件.

public final <U> Observable<T> debounce(Function<? super T,? extends ObservableSource<U>> debounceSelector)

public final Observable<T> debounce(long timeout,
                                    java.util.concurrent.TimeUnit unit)

同样还有一种实现方式

public final Observable<T> throttleWithTimeout(long timeout,

public final Observable<T> throttleWithTimeout(long timeout,
                                               java.util.concurrent.TimeUnit unit,
                                               Scheduler scheduler)

Filter

筛选事件,例如字符串为空则不发送事件

Observable.just(1, 20, 65, -5, 7, 19)
                .filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(@NonNull Integer integer) throws Exception {
                      // 根据返回结果布尔类型确定是否拦截事件
                        return integer >= 10;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                
            }
        });

All

判断所有事件是否符合条件, 回调函数会执行多次但是观察者只能收到一个布尔类型值;

public final Single<java.lang.Boolean> all(Predicate<? super T> predicate)
Flowable.just(1, 2, 3, 4).all(new Predicate<Integer>() {
    @Override public boolean test(Integer integer) throws Exception {
        return integer < 4;
    }
}).subscribe(new Consumer<Boolean>() {
    @Override public void accept(Boolean aBoolean) throws Exception {

    }
});

First

只发射第一个事件, 如果没有发射事件直接onComplete()则会发射指定参数.

返回值为Single, 其被观察者不存在onComplete函数.

public final Single<T> first(T defaultItem)

public final Single<T> firstOrError()
// 如果仅onComplete会发射onError

Last

只发射最后一个事件, 如果没有发射事件直接onComplete()则会发射指定参数.

public final Single<T> last(T defaultItem)

Amb

仅仅处理第一个发射事件的被观察者, 其他的观察者都会被抛弃.

要求添加的所有被观察者的事件类型需要统一;

public static <T> Observable<T> amb(java.lang.Iterable<? extends ObservableSource<? extends T>> sources)
// 集合类型

ambArray

和上面函数区别仅仅是参数变成可变参数

public static <T> Observable<T> ambArray(ObservableSource<? extends T>... sources)
// 可变参数类型

AmbWith

非静态函数, 结束对源被观察者的订阅, 然后对当前指定参数的被观察者订阅, 类似切换一个被观察者.

public final Observable<T> ambWith(ObservableSource<? extends T> other)

Blocking

该操作符会打断RxJava的链式调用直接事件

只发送第一个或|最后一个事件

public final T blockingFirst()

public final T blockingFirst(T defaultItem)

public final T blockingLast()

public final T blockingLast(T defaultItem)

public final T blockingSingle()
  • 如果没有设置默认值的话, 被观察者事件为空将抛出异常
  • 使用single, 但是如果observable的事件不止一个, 将抛出异常

示例:

Long aLong = Observable.intervalRange(0, 5, 1, 1, TimeUnit.SECONDS)
.blockingFirst();

循环

public final void blockingForEach(Consumer<? super T> onNext)

public final java.lang.Iterable<T> blockingIterable()

public final java.lang.Iterable<T> blockingIterable(int bufferSize)

public final java.lang.Iterable<T> blockingMostRecent(T initialValue)

public final void blockingSubscribe()

限制接受事件

  • 指定时间内 第一个
  • 指定时间内 最后一个

ThrottleFirst

只发送一定时间内的第一个事件, 默认在ComputationScheduler上执行, 但是可以指定Scheduler

public final Observable<T> throttleFirst(long windowDuration,
                                         java.util.concurrent.TimeUnit unit)

public final Observable<T> throttleFirst(long skipDuration,
                                             java.util.concurrent.TimeUnit unit,
                                             Scheduler scheduler)

ThrottleLast

只发送一定时间内的最后一个事件

public final Observable<T> throttleLast(long  intervalDuration, 
                                        java.util.concurrent.TimeUnit unit)

public final Observable<T> throttleLast(long intervalDuration,
                                                                java.util.concurrent.TimeUnit unit,
                                                                Scheduler scheduler)

ThrottleWithTimeout

发送事件A后将触发计时, 如果规定时间内有新的事件B发送, 将丢弃事件A; 功能和debounce 相同, 但是debounce可以添加一个Observable作为计时;

可以理解为只接受一定时间内的最后一个事件

public final Observable<T> throttleWithTimeout(long timeout,
                                               java.util.concurrent.TimeUnit unit)

public final Observable<T> throttleWithTimeout(long timeout,
                                                 java.util.concurrent.TimeUnit unit,
                                                 Scheduler scheduler)

Sample

控制间隔, 在一定时间内只取最后发射的事件, 可以指定线程. 等同于throttleLast

public final Observable<T> sample(long period,
                                   java.util.concurrent.TimeUnit unit)

public final Observable<T> sample(long period,
                                  java.util.concurrent.TimeUnit unit,
                                 boolean emitLast)
public final <U> Observable<T> sample(ObservableSource<U> sampler)

public final <U> Observable<T> sample(ObservableSource<U> sampler,
                                                              boolean emitLast)

TimeOut

  public final Observable<T> timeout(long timeout,
                                     java.util.concurrent.TimeUnit timeUnit)


  public final Observable<T> timeout(long timeout,
                                     java.util.concurrent.TimeUnit timeUnit,
                                     ObservableSource<? extends T> other)
  1. 设置一个超时的时间间隔, 如果发送事件的间隔超过这个事件就会发出一个异常事件TimeoutException(进入onError).
  2. 如果你不想发出的是异常而是发送一个新的被观察者事件, 就可以使用该方法

和上面的操作符不同的是, 这个操作符是通过回调函数返回的Observable来控制超时时间; 如果返回的Observable发送了事件但是源被观察者还未发送事件, 将判断为超时; 进入onError抛出TimeOutException

public final <V> Observable<T> timeout(Function<? super T,? extends ObservableSource<V>> itemTimeoutIndicator)

public final <V> Observable<T> timeout(Function<? super T,? extends ObservableSource<V>> itemTimeoutIndicator,
                                         ObservableSource<? extends T> other)

以下重载可以给第一项被观察者发送的事件单独设置一个超时参数(Observable)

public final <U,V> Observable<T> timeout(ObservableSource<U> firstTimeoutIndicator,
                                         Function<? super T,? extends ObservableSource<V>> itemTimeoutIndicator)

public final <U,V> Observable<T> timeout(ObservableSource<U> firstTimeoutIndicator,
                                           Function<? super T,? extends ObservableSource<V>> itemTimeoutIndicator,
                                           ObservableSource<? extends T> other)

跳过事件

  • 数量
  • 指定时间
  • 倒序跳过
  • 指定被观察者发送完毕
  • 回调函数连续跳过

Skip

跳过事件

public final Observable<T> skip(long count)
// 跳过指定数量的事件

public final Observable<T> skip(long time,
                                  java.util.concurrent.TimeUnit unit)
// 跳过指定时间内的事件

SkipLast

从后开始跳过发送事件;

public final Observable<T> skipLast(int count)

public final Observable<T> skipLast(long time,
                                      java.util.concurrent.TimeUnit unit)

public final Flowable<T> skipLast(long time,
                                    java.util.concurrent.TimeUnit unit,
                                    boolean delayError)

SkipUntil

在作为参数的被观察者没有发送完事件之前的所有源被观察者的事件都将被跳过;

public final <U> Observable<T> skipUntil(ObservableSource<U> other)

示例代码:

Observable.intervalRange(0, 5, 1, 1, TimeUnit.SECONDS)
    // 如果下面的被观察者的事件没有发送完毕(不包括onComplete)源被观察者的事件都将被跳过
    .skipUntil(Observable.just(1)
        .delay(2, TimeUnit.SECONDS)) 
    .subscribe(new Consumer<Long>() {
      @Override
      public void accept(Long aLong) throws Exception {
        Log.d("日志",
            "(MainActivity.java:80) ___ " + "accept() called with: aLong = [" + aLong + "]");
      }
    });

SkipWhile

在回调中判断是否抛弃事件;

和过滤操作符filter不同的是skipWhile只能从开头开始连续跳过事件, 即如果第一个事件你没有跳过, 那么该回调函数就不会再次执行, 也就是你之后都无法跳过事件了.

public final Observable<T> skipWhile(Predicate<? super T> predicate)

停止订阅

  • 可以接受的最多事件数量
  • 可以接收到事件的时间
  • 参数被观察者发送事件将停止源被观察者的订阅状态
  • 倒序
  • 回调函数判断是否停止

Take

该函数和Skip类似, 但是他是如果第一次阻止发射器继续发射事件, 就会直接进入onComplete回调

public final Observable<T> take(long count)
// 控制最多接受到的事件数量

public final Observable<T> take(long time,
                               java.util.concurrent.TimeUnit unit)
// 控制只有规定时间内才能接受到事件

TakeUntil

public final <U> Observable<T> takeUntil(ObservableSource<U> other)
// 参数观察者发送事件就会导致源观察者被结束事件发送

public final Observable<T> takeUntil(Predicate<? super T> stopPredicate)
// 通过回调来判断是否结束事件的发送, 返回true结束发射器发射事件

TakeLast

public final Observable<T> takeLast(int count)

public final Observable<T> takeLast(long count,
                                      long time,
                                      java.util.concurrent.TimeUnit unit)

public final Observable<T> takeLast(long time,
                                      java.util.concurrent.TimeUnit unit)

public final Observable<T> takeLast(long time,
                                      java.util.concurrent.TimeUnit unit,
                                      boolean delayError)

TakeWhile

再回调中判断是否结束发射器(同样进入onComplete), 但是和TakeUntil不同的是返回false为结束.

public final Observable<T> takeWhile(Predicate<? super T> predicate)

Join

添加一个被观察者(称为目标被观察者), 该被观察者发送的每个事件都将依次和源被观察者的所有事件结合(在同一个回调函数中传入)

public final <TRight,TLeftEnd,TRightEnd,R> Observable<R> join(ObservableSource<? extends TRight> other,
                                                                                      Function<? super T,? extends ObservableSource<TLeftEnd>> leftEnd,
                                                                                      Function<? super TRight,? extends ObservableSource<TRightEnd>> rightEnd,
                                                                                      BiFunction<? super T,? super TRight,? extends R> resultSelector)

示例代码:

    Observable.just(1L, 2L, 3L, 4L)
        .join(Observable.just(5L, 6L, 7L, 8L), new Function<Long, ObservableSource<Long>>() {

          /**
           * 接受源被观察者事件
           * @param aLong
           * @return 返回的被观察者发送事件后将终止源被观察者的事件发送
           * @throws Exception
           */
          @Override
          public ObservableSource<Long> apply(Long aLong) throws Exception {
            Log.d("日志",
                "(MainActivity.java:65) ___ " + "源被观察者 aLong = [" + aLong + "]");
            return Observable.interval(3, TimeUnit.SECONDS);
          }
        }, new Function<Long, ObservableSource<Long>>() {

          /**
           * 接受添加的被观察者事件(join Observable)
           * @param aLong
           * @return 返回的被观察者发送事件后就将终止添加的被观察者的
           * @throws Exception
           */
          @Override
          public ObservableSource<Long> apply(Long aLong) throws Exception {
            Log.d("日志",
                "(MainActivity.java:75) ___ " + "被添加的被观察者 aLong = [" + aLong + "]");
            return Observable.interval(3, TimeUnit.SECONDS);
          }
        }, new BiFunction<Long, Long, String>() {
          /**
           * 同时接受被添加的被观察者和源被观察者的事件
           * @param aLong 源被观察者发送的事件
           * @param aLong2 被添加的被观察者发送的事件
           * @return 该返回值最终被观察者接收到
           * @throws Exception
           */
          @Override
          public String apply(Long aLong, Long aLong2) throws Exception {
            Log.d("日志", "(MainActivity.java:89) ___ " + "apply() called with: aLong = [" + aLong
                + "], aLong2 = [" + aLong2 + "]");
            return aLong + "" + aLong2;
          }
        })
        .subscribe(new Consumer<String>() {
          @Override
          public void accept(String s) throws Exception {
            Log.d("日志", "(MainActivity.java:83) ___ " + "accept() called with: s = [" + s + "]");
          }
        });

GroupJoin

和Join类似

public final <TRight,TLeftEnd,TRightEnd,R> Observable<R> groupJoin(ObservableSource<? extends TRight> other,
                                                                                           Function<? super T,? extends ObservableSource<TLeftEnd>> leftEnd,
                                                                                           Function<? super TRight,? extends ObservableSource<TRightEnd>> rightEnd,
                                                                                           BiFunction<? super T,? super Observable<TRight>,? extends R> resultSelector)

示例:

    Observable.just(1L, 2L, 3L, 4L)
        .groupJoin(Observable.just(5L, 6L, 7L, 8L),
            new Function<Long, ObservableSource<Long>>() {
              @Override
              public ObservableSource<Long> apply(Long aLong) throws Exception {
                return null;
              }
            }, new Function<Long, ObservableSource<Long>>() {
              @Override
              public ObservableSource<Long> apply(Long aLong) throws Exception {
                return null;
              }
            }, new BiFunction<Long, Observable<Long>, String>() {
              @Override
              public String apply(Long aLong, Observable<Long> longObservable) throws Exception {
                return null;
              }
            })
        .subscribe(new Consumer<String>() {
          @Override
          public void accept(String s) throws Exception {
            Log.d("日志", "(MainActivity.java:78) ___ " + "accept() called with: s = [" + s + "]");
          }
        });

ToMap

public final <K> Single<java.util.Map<K,T>> toMap(Function<? super T,? extends K> keySelector)

public final <K,V> Single<java.util.Map<K,V>> toMap(Function<? super T,? extends K> keySelector,
                                                        Function<? super T,? extends V> valueSelector)


public final <K,V> Single<java.util.Map<K,V>> toMap(Function<? super T,? extends K> keySelector,
                                                        Function<? super T,? extends V> valueSelector,
                                                        java.util.concurrent.Callable<? extends java.util.Map<K,V>> mapSupplier)

错误处理

onErrorResumeNext

如果发生异常将接收到一个回调返回另一个被观察者(执行OnNext不执行onError)

// 订阅另一个被观察者
public final Observable<T> onErrorResumeNext(ObservableSource<? extends T> next)

onErrorReturn

如果发生异常将接收到一个回调返回事件(执行OnNext不执行onError)

public final Observable<T> onErrorReturn(Function<? super java.lang.Throwable,? extends T> valueSupplier)

两个操作符最后都会执行onComplete

Retry

当被观察者的发射器发出异常事件(onError)以后会执行重试操作

public final Observable<T> retry()
// 当发生错误将重新发送事件(被观察者的所有事件全部重新发送)

public final Observable<T> retry(long times)
// 重新发送的次数


public final Observable<T> retry(Predicate<? super java.lang.Throwable> predicate)

public final Observable<T> retry(BiPredicate<? super java.lang.Integer,? super java.lang.Throwable> predicate)
// 在回调函数中判断是否重试(和上面的操作符不同的是该回调函数里面会有一个重试次数的参数)

public final Observable<T> retry(long times,  Predicate<? super java.lang.Throwable> predicate)
// 判断函数 + 重试次数

RetryUntil

该操作符其实Retry已经有相同实现retry(predicate)

不同的是返回true表示停止重试

public final Observable<T> retryUntil(BooleanSupplier stop)

RetryWhen

在回调函数中返回一个被观察者, 该被观察者如果发出错误事件就会导致源被观察者重试. 如果没有发出错误事件就不会触发重试;

public final Observable<T> retryWhen(Function<? super Observable<java.lang.Throwable>,? extends ObservableSource<?>> handler)

示例:

该示例不会触发重试;

    Observable.create(
            new ObservableOnSubscribe<Integer>() {
              @Override
              public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onError(null);
                emitter.onNext(3);
              }
            })
        .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                return Observable.just(23);
            }
        })
        .subscribe(
            new DefaultObserver<Integer>() {
              @Override
              public void onNext(Integer integer) {
                System.out.println("integer = [" + integer + "]");
              }

              @Override
              public void onError(Throwable e) {
                System.out.println("Main.onError");
              }

              @Override
              public void onComplete() {
                System.out.println("Main.onComplete");
              }
            });

判断操作

Contains

判断发射的事件是否包含指定的事件, 观察者得到一个布尔类型的值

public final Single<java.lang.Boolean> contains(java.lang.Object element)

Any

public final Single<java.lang.Boolean> any(Predicate<? super T> predicate)

依次判断每个事件, 如果返回true则马上终止发射器

    Observable.just(1, 2, 3, 4).any(new Predicate<Integer>() {
      @Override public boolean test(Integer integer) throws Exception {
        Log.d("日志",
            "(MainActivity.java:27) ___ " + "test() called with: integer = [" + integer + "]");
        if (integer == 3) {
          return true;
        } else {
          return false;
        }
      }
    }).subscribe(new Consumer<Boolean>() {
      @Override public void accept(Boolean aBoolean) throws Exception {
        Log.d("日志",
            "(MainActivity.java:33) ___ " + "accept() called with: aBoolean = [" + aBoolean + "]");
      }
    });

IsEmpty

public final Single<java.lang.Boolean> isEmpty()

判断是否有发射过事件, 观察者得到个布尔类型的值.

DefaultIfEmpty

public final Observable<T> defaultIfEmpty(T defaultItem)

如果发射器没有发射任何事件, 就会发射一个指定的默认事件, 例如发射器的事件被拦截

SwitchIfEmpty

public final Observable<T> switchIfEmpty(ObservableSource<? extends T> other)

如果没有发射事件就用另一个被观察者替代

Flowable.empty()
        .switchIfEmpty(Flowable.just(3, 4, 5))
        .subscribe(ele -> Log.i("tag", String.valueOf(ele)));

SequenceEqual

public static <T> Single<java.lang.Boolean> sequenceEqual(ObservableSource<? extends T> source1,
                                                          ObservableSource<? extends T> source2,
                                                          BiPredicate<? super T,? super T> isEqual)
// 最后的

public static <T> Single<java.lang.Boolean> sequenceEqual(ObservableSource<? extends T> source1,
                                                              ObservableSource<? extends T> source2)

会比较两个被观察者是否相同, 然后观察者接受一个布尔类型的值, 发射的事件数量不相同, 类型不相同都会为false. 只要判断到不相同马上就会终止事件的发送.

    Observable.sequenceEqual(Observable.intervalRange(0, 3, 0, 1, TimeUnit.SECONDS),
        Observable.just(0l, 1l, 2l), new BiPredicate<Long, Long>() {
          @Override public boolean test(Long aLong, Long aLong2) throws Exception {
            // 在这里判断是否相等
            return false;
          }
        }).subscribe(new Consumer<Boolean>() {
      @Override public void accept(Boolean aBoolean) throws Exception {
        // 最终结果
      }
    });

合并操作

Reduce

相加操作符, 每次都可以两个事件一起处理, 然后所有事件都被处理后就会被观察者接受到最终的事件

public final Maybe<T> reduce(BiFunction<T,T,T> reducer)

第一次处理(apply)会接收到事件1和事件2, 然后第N次就是上次处理的结果(apply的返回值)和事件N

示例:

Observable.just(1, 2, 3, 4).reduce(new BiFunction<Integer, Integer, Integer>() {
  /**
       *  该方法会回调多次直到所有事件都依次相加(或者说操作)以后才会被观察者接收到最终的结果
       * @throws Exception
       */
  @Override public Integer apply(Integer integer, Integer integer2) throws Exception {
    // 三个泛型分别对应 上次运行结果 当前事件 返回值
    return integer + integer2;
  }
}).subscribe(new Consumer<Integer>() {
  @Override public void accept(Integer integer) throws Exception {
  }
});

待定操作符

public final <R> Single<R> reduce(R seed,
                                  BiFunction<R,? super T,R> reducer)

public final <R> Single<R> reduceWith(java.util.concurrent.Callable<R> seedSupplier,
                                      BiFunction<R,? super T,R> reducer)

Scan

和Reduce类似, 但是每次观察者都能收到回调参数的返回值结果作为事件

public final Observable<T> scan(BiFunction<T,T,T> accumulator)
    
public final <R> Observable<R> scan(R initialValue, // 加入一个初始化的值
                                    BiFunction<R,? super T,R> accumulator)

ScanWith

public final <R> Observable<R> scanWith(java.util.concurrent.Callable<R> seedSupplier,
                                        BiFunction<R,? super T,R> accumulator)

Collect

可以创建容器来依次操作数据(观察者只会收到一次事件, 也就是容器)

    Flowable.just(1, 2, 3)
        .collect(
            new Callable<ArrayList<Integer>>() {//创建收集容器
              @Override
              public ArrayList<Integer> call() throws Exception {
                return new ArrayList<>();
              }
            }, new BiConsumer<ArrayList<Integer>, Integer>() {//创建收集
              @Override
              public void accept(ArrayList<Integer> list, Integer integer)
                  throws Exception {//前者容器,后者数据
                list.add(integer);
              }
            })
        .subscribe(ele -> Log.d("日志", "(MainActivity.java:33) ___ Result = " + String.valueOf(ele)));

时间

Delay

delay操作符会延迟每个事件发送的时间(包括onComplete但不包括onError)

public final Observable<T> delay(long delay,
                                 TimeUnit unit)

public final <U> Observable<T> delay(Function<? super T,? extends ObservableSource<U>> itemDelay)
// 回调参数如果发送onNext就会导致延迟结束

TimeStamp

该操作符将事件和发送的时间都封装到一个对象Timed

public final Observable<Timed<T>> timestamp()

public final Observable<Timed<T>> timestamp(Scheduler scheduler)

public final Observable<Timed<T>> timestamp(TimeUnit unit)

public final Observable<Timed<T>> timestamp(TimeUnit unit,
                                            Scheduler scheduler)

示例:

Observable.intervalRange(0, 5, 2, 2, TimeUnit.SECONDS)
        .timestamp()
        .subscribe(new Consumer<Timed<Long>>() {
          @Override
          public void accept(Timed<Long> longTimed) throws Exception {
            Log.d("日志","accept() called with: longTimed = [" + longTimed + "]");
          }
        });

结果

longTimed = [Timed[time=1525735346216, unit=MILLISECONDS, value=2]]

Count

观察者将接收到事件数量, 而无法收到事件本身.

Flowable.just(1,2,3,4,5).count().subscribe(new BiConsumer<Long, Throwable>() {
    @Override public void accept(Long aLong, Throwable throwable) throws Exception {
        Log.d("日志", "(MainActivity.java:18) ___ Result = " + aLong);
    }
});

BackPressure

意为"背压"

了解了Observable和Flowable的区别,我们还不知什么叫做背压,下面我们来简单了解下概念。所谓背压就是生产者(被观察者)的生产速度大于消费者(观察者)消费速度从而导致的问题。

举一个简单点的例子,如果被观察者快速发送消息,但是观察者处理消息的很缓慢,如果没有特定的流(Flow)控制,就会导致大量消息积压占用系统资源,最终导致十分缓慢。

同步线程是不可能产生这种问题, 观察者没有处理完事件就不可能再次发送事件.

怎么优化和减少这种情况后面再探讨,不过可以注意到,Flowable创建的时候已经设置了BackpressureStrategy,而且Subscriber使用了request来控制最大的流量。

被观察者

Hot Observable

热观察者: 没有订阅就开始发送事件, 订阅只会受到订阅之后发送的事件.

重放

  • 线程
  • 时间
  • 时间单位
  • 缓存大小
public final ConnectableObservable<T> replay()

ConnectableObservable

ConnectableObservable只有在使用函数connect以后才会让观察者收到事件

public final Disposable connect()

public abstract void connect(Consumer<? super Disposable> connection)

自动连接, 但是不会在所有观察者取消订阅时断开上游事件

public Observable<T> autoConnect()

public Observable<T> autoConnect(int numberOfSubscribers) // 当N个观察者订阅时自动connect

public Observable<T> autoConnect(int numberOfSubscribers,
                        Consumer<? super Disposable> connection) // 该回调中可以得到Dispose对象用于取消上游

该函数会在第一个观察者订阅时connect, 在所有观察者取消订阅时结束上游事件发送.

public Observable<T> refCount()

public final Observable<T> share() // 等同于publish和refCount

Observable

不支持背压的被观察者, 性能高

ObservableSource

Flowable

支持背压的被观察者, 性能略比Observable低, 函数体系和Observable有所区别.

Publisher

Publisher该类属于Flowable的根接口, ObservableSource属于Observable的根接口;

Single

该被观察者只能发出一个事件, 重复发送不会受到(因为只能发送一条事件所以不存在背压).

Single.create(object : SingleOnSubscribe<Int> {
    override fun subscribe(emitter: SingleEmitter<Int>) {
        emitter.onSuccess(12)
    }
}).subscribe(object : SingleObserver<Int?> {
    override fun onSuccess(t: Int) {
    }

    override fun onSubscribe(d: Disposable) {
    }

    override fun onError(e: Throwable) {
    }
})

DisposableSingleObserver

可以手动断开观察者

public final void dispose()

public final boolean isDisposed()

ResourceSingleObserver

可以添加其他的Disposable, 然后一起取消观察者

public final void add(Disposable resource)

其他被观察者基本都遵守这几个规则有类似名称的观察者类

Completable

如果你的观察者连onNext事件都不关心,你可以使用Completable,他只有onComplete和onError两个事件:

Completable.create(new CompletableOnSubscribe() {//被观察者

    @Override
    public void subscribe(CompletableEmitter e) throws Exception {
        e.onComplete();//单一onComplete或者onError
    }

}).subscribe(new CompletableObserver() {//观察者
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onComplete() {

    }

    @Override
    public void onError(Throwable e) {

    }
});

同样也可以使用Actions来简化Observer:

  • completable.subscribe(onComplete)
  • completable.subscribe(onComplete,onError)

要转换成其他类型的被观察者,也是可以使用toFlowable()toObservable()等方法去转换。

Maybe

如果你有一个需求是可能发送一个数据或者不会发送任何数据,这时候你就需要Maybe,它类似于Single和Completable的混合体。

Maybe可能会调用以下其中一种情况(也就是所谓的Maybe):

  • onSuccess或者onError
  • onComplete或者onError

可以看到onSuccess和onComplete是互斥的存在,例子代码如下:

//被观察者
Maybe<String> maybe = Maybe.create(new MaybeOnSubscribe<String>() {
    @Override
    public void subscribe(MaybeEmitter<String> e) throws Exception {
        e.onSuccess("test");//发送一个数据的情况,或者onError,不需要再调用onComplete(调用了也不会触发onComplete回调方法)
        //e.onComplete();//不需要发送数据的情况,或者onError
    }
});

//订阅观察者
maybe.subscribe(new MaybeObserver<String>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onSuccess(String s) {
        //发送一个数据时,相当于onNext和onComplete,但不会触发另一个方法onComplete
        Log.i("tag", s);
    }

    @Override
    public void onComplete() {
        //无数据发送时候的onComplete事件
        Log.i("tag", "onComplete");
    }

    @Override
    public void onError(Throwable e) {

    }

});

Subject

同时继承ObservableObserver

AsyncSubject

该被观察者只会发送最后一个事件(同时onComplete)

要求必须手动执行onComplete()才会接收到最后一个事件和onComplete, 不论订阅前后.

如果出现异常终止任何事件

BehaviorSubject

只能观察到订阅前最后一个事件和订阅之后所有事件

PublishSubject

只观察订阅后发送的事件;

ReplaySubject

无论订阅前后事件都能观察到

UnicastSubject

只允许被观察者订阅一次, 否则抛出异常.

SerializedSubject

用于多线程发射事件. 只需要包装被观察者即可.

线程安全

如果多个线程都发射事件, 需要使用以下函数转换, 才会进入队列依次等待发射事件.

public final Subject<T> toSerialized()

SerializedSubject已经不允许直接创建

观察者

  • Action:无参数类型

  • Consumer:单一参数类型

  • BiConsumer<T1, T2>:双参数类型

  • Consumer<Obejct[]>:多参数类型

测试

用于测试RxJava的事件类

TestObserver

TestScheduler

对于某些需要经过一定时间的轮循器等事件观察者

// 时间快速经过多少
public void advanceTimeBy(long delayTime,
                 java.util.concurrent.TimeUnit unit)

// 时间直接到某个点
public void advanceTimeTo(long delayTime,
                 java.util.concurrent.TimeUnit unit)

TestSubsriber

    @Test public void addition_isCorrect() throws Exception {
        TestSubscriber<String> testSubscriber = new TestSubscriber<>();
        //依次发射A,B,C
        Flowable.just("A", "B", "C").subscribe(testSubscriber);

        //断言值是否不存在
        testSubscriber.assertNever("D");
        //断言值是否相等
        testSubscriber.assertValues("A", "B", "C");
        //断言值的数量是否相等
        testSubscriber.assertValueCount(3);
        //断言是否结束
        testSubscriber.assertTerminated();
    }