RxJava2 五大重要角色介绍

目录

RxJava2 的5大基类及本章学习结构图

1、Flowable

1.1、Flowable简介

1.2、Flowable官方图解

1.3、Backpressure

2、Observable

2.1、Observable简介

2.2、Observable官方图解

2.3、Flowable和Observable对比

2.4、形象理解ObservableSource和Publisher有何异同

3、Single

3.1、Single简介

3.2、Single与Observable的区别

3.3、Single官方图解

4、Completable

4.1、Completable简介

4.2、Completable官网图解

4.3、Completable示例

5、Maybe

5.1、Maybe简介

5.2、Maybe官方图解

5.3、Maybe示例

6、总结:


开篇

开始学习RxJava的时候忘记所有,仅仅就学习RxJava,单独看待,不需要和Retrofit等等其它库结合使用,当我们明白RxJava的操作符等一些列api怎么使用在什么场景下使用后再来结合Retrofit来进行网络请求等,这样或许会更加清晰点。

RxJava2 的5大基类及本章学习结构图

1、Flowable

1.1、Flowable简介

Flowable类,用于实现Reactive-Streams模式,并提供工厂方法,中间运算符以及使用反应式数据流的能力。

Reactive-Streams使用Flowable运行,Flowable实现了Publishers。因此,许多运算符直接接受Publishers,并允许与其他Reactive-Streams的实现进行直接交互操作

public abstract class Flowable<T> implements Publisher<T>

Flowable为操作符提供128个元素的默认缓冲区大小,可通过bufferSize() 方法获取,可通过系统参数rx2.buffer-size全局覆盖。但是大多数运算符都有重载,允许显式设置其内部缓冲区大小。

    /** The default buffer size. */
    static final int BUFFER_SIZE;
    static {
        BUFFER_SIZE = Math.max(16, Integer.getInteger("rx2.buffer-size", 128));
    }

    /**
     * Returns the default internal buffer size used by most async operators.
     * <p>The value can be overridden via system parameter {@code rx2.buffer-size}
     * <em>before</em> the Flowable class is loaded.
     * @return the default internal buffer size.
     */
    public static int bufferSize() {
        return BUFFER_SIZE;
    }

1.2、Flowable官方图解

1)看到上图有点疑问,不是在说Flowable嘛,怎么图解里的说明是Observable呢?

2)其实在官方文档里面Flowable和Observable都使用的是上面这个图解,因此这两个类肯定是提供相似功能,既然是相似,那么这幅图就是他们的共性,那不同的地方是什么呢?

不同之处是:Flowable支持Backpressure,Observable不支持Backpressure;

3)Backpressure什么是?

看下面1.3节

1.3、Backpressure

Backpressure中文翻译过来是背压,这里推荐一篇很好的关于Backpressure说明的博客:关于RxJava最友好的文章——背压(Backpressure)

下面关于背压的说明是出自拉丁吴博客的内容,写的很通俗易懂

RxJava是一个观察者模式的架构,当这个架构中被观察者(Observable)和观察者(Subscriber)处在不同的线程环境中时,由于者各自的工作量不一样,导致它们产生事件和处理事件的速度不一样,这就会出现两种情况:

  • 被观察者产生事件慢一些,观察者处理事件很快。那么观察者就会等着被观察者发送事件,(好比观察者在等米下锅,程序等待,这没有问题)
  • 被观察者产生事件的速度很快,而观察者处理很慢。那就出问题了,如果不作处理的话,事件会堆积起来,最终挤爆你的内存,导致程序崩溃。(好比被观察者生产的大米没人吃,堆积最后就会烂掉)

下面我们用代码演示一下这种崩溃的场景:

//被观察者在主线程中,每1ms发送一个事件
Observable.interval(1, TimeUnit.MILLISECONDS)
                //.subscribeOn(Schedulers.newThread())
                //将观察者的工作放在新线程环境中
                .observeOn(Schedulers.newThread())
                //观察者处理每1000ms才处理一个事件
                .subscribe(new Action1<Long>() {
                      @Override
                      public void call(Long aLong) {
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          Log.w("TAG","---->"+aLong);
                      }
                  });

拉丁吴对Backpressure的定义是:

背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略

简而言之,背压是流速控制的一种策略

需要强调两点:

  • 背压策略的一个前提是异步环境,也就是说,被观察者和观察者处在不同的线程环境中。
  • 背压(Backpressure)并不是一个像flatMap一样可以在程序中直接使用的操作符,他只是一种控制事件流速的策略。

关于背压(Backpressure)的解释拉丁吴说的很清楚了,要了解更多关于这方面的信息可以移步他的博客:关于RxJava最友好的文章——背压(Backpressure)

2、Observable

2.1、Observable简介

Observable类是不支持背压的,Observable是Reactive的一个抽象基类,Observable提供工厂方法,中间运算符以及消费同步和/或异步数据流的功能。

Observable类中的多数运算符接受一个或者多个ObservableSource,ObservableSource是非背压的基本接口,Observable实现了这个接口。

public abstract class Observable<T> implements ObservableSource<T>

默认情况下,Observable的为其运算符提供128个元素的缓冲区大小运行,可看考Flowable.bufferSize(),可以通过系统参数rx2.buffer-size全局覆盖。但是,大多数运算符都有重载,允许设置其内部缓冲区大小。

2.2、Observable官方图解

与Flowable是一样的

2.3、Flowable和Observable对比

在1.2节中已经说明了二者最大的区别。

官方也给出的解释是:

The design of this class was derived from the Reactive-Streams design and specification by removing any backpressure-related infrastructure and implementation detail, replacing the org.reactivestreams.Subscription with Disposable as the primary means to dispose of a flow.

中文翻译:

该类的设计源自Reactive-Streams设计和规范,通过删除任何与背压相关的基本结构和实现细节,将Disposable替换为org.reactivestreams.Subscription作为处理流的主要方式。

从代码层面上做简单的说明

Flowable实现了Publisher接口,Publisher源码如下

public interface Publisher<T> {

    /**
     * Request {@link Publisher} to start streaming data.
     * <p>
     * This is a "factory method" and can be called multiple times, each time starting a new {@link Subscription}.
     * <p>
     * Each {@link Subscription} will work for only a single {@link Subscriber}.
     * <p>
     * A {@link Subscriber} should only subscribe once to a single {@link Publisher}.
     * <p>
     * If the {@link Publisher} rejects the subscription attempt or otherwise fails it will
     * signal the error via {@link Subscriber#onError}.
     *
     * @param s the {@link Subscriber} that will consume signals from this {@link Publisher}
     */
    public void subscribe(Subscriber<? super T> s);
}

Observable实现了ObservableSource接口,ObservableSource源码如下

public interface ObservableSource<T> {

    /**
     * Subscribes the given Observer to this ObservableSource instance.
     * @param observer the Observer, not null
     * @throws NullPointerException if {@code observer} is null
     */
    void subscribe(Observer<? super T> observer);
}

对比ObservableSource和Publisher,都有一个同名的接口subscribe()

2.4、形象理解ObservableSource和Publisher有何异同

ObservableSource:可观察源

Publisher:发布者

subscribe:订阅

Subscriber:订阅者

Observer:观察者

对于ObservableSource,可以将subscribe(Observer observer)理解为Observer通过subscribe订阅了ObservableSource

对于Publisher,可以将subscribe(Subscriber s)理解为Subscriber通过subscribe订阅了Publisher

上面的解释可能比较抽象,通俗的举个例子,来个角色扮演

第一组:报刊(ObservableSource)、报刊订阅者(Observer)、订阅报刊的行为(subscribe)

第二组:报刊发布人(Publisher)、报刊订阅者(Subscriber)、订阅报刊的行为(subscribe)

把这个场景串起来讲就是:报刊订阅者订阅了报刊,或者说报刊订阅者在报刊发布人手中订阅了报刊。

这其实是典型的观察者模式,所不同的是信息的发布者是ObservableSource还是Publisher,信息的订阅者是Observer还是Subscriber,统一的行为都是subscribe。

3、Single

3.1、Single简介

public abstract class Single<T> implements SingleSource<T> 

Single实现了SingleSource

/**
 * Represents a basic {@link Single} source base interface,
 * consumable via an {@link SingleObserver}.
 * <p>
 * This class also serves the base type for custom operators wrapped into
 * Single via {@link Single#create(SingleOnSubscribe)}.
 *
 * @param <T> the element type
 * @since 2.0
 */
public interface SingleSource<T> {

    /**
     * Subscribes the given SingleObserver to this SingleSource instance.
     * @param observer the SingleObserver, not null
     * @throws NullPointerException if {@code observer} is null
     */
    void subscribe(SingleObserver<? super T> observer);
}

Single类为单个值响应实现Reactive Pattern。

Single和Observable类似,所不同的是Single只能发出一个值,要么发射成功要么发射失败,也没有“onComplete”作为完成时的回调

Single类实现了基类SingleSource的接口,SingleObserver作为Single发出来的消息的默认消费者,SingleObserver通过subscribe(SingleObserver<? super T> observer)在Single中订阅消息

public interface SingleObserver<T> {

    /**
     * Provides the SingleObserver with the means of cancelling (disposing) the
     * connection (channel) with the Single in both
     * synchronous (from within {@code onSubscribe(Disposable)} itself) and asynchronous manner.
     * @param d the Disposable instance whose {@link Disposable#dispose()} can
     * be called anytime to cancel the connection
     * @since 2.0
     */
    void onSubscribe(Disposable d);

    /**
     * Notifies the SingleObserver with a single item and that the {@link Single} has finished sending
     * push-based notifications.
     * <p>
     * The {@link Single} will not call this method if it calls {@link #onError}.
     *
     * @param value
     *          the item emitted by the Single
     */
    void onSuccess(T value);

    /**
     * Notifies the SingleObserver that the {@link Single} has experienced an error condition.
     * <p>
     * If the {@link Single} calls this method, it will not thereafter call {@link #onSuccess}.
     *
     * @param e
     *          the exception encountered by the Single
     */
    void onError(Throwable e);
}

3.2、Single与Observable的区别

Single只能发送单个消息,不能发送消息流,而且观察者接收到消息也只有两种情况,要么接收成功,要么接收失败

3.3、Single官方图解

4、Completable

4.1、Completable简介

Completable类表示延迟计算,没有任何值,只表示完成或异常。

Completable的行为类似于Observable,在计算完成后只能发出完成或错误信号,由onComplete或onError接口来处理,没有onNext或onSuccess等回调接口

Completable实现了基类CompletableSource的接口,CompletableObserver通过subscribe()方法在Completable处订阅消息。

Completable遵循协议:onSubscribe (onComplete | onError)

public abstract class Completable implements CompletableSource
public interface CompletableSource {

    /**
     * Subscribes the given CompletableObserver to this CompletableSource instance.
     * @param cs the CompletableObserver, not null
     * @throws NullPointerException if {@code cs} is null
     */
    void subscribe(CompletableObserver cs);
}

public interface CompletableObserver {

    void onSubscribe(Disposable d);

    void onComplete();

    void onError(Throwable e);
}

从源码中我们可以看到CompletableObserver里面有三个接口,

1)onSubscribe中传入参数Disposable,由Completable调用一次,在CompletableObserver实例上设置Disposable,然后可以随时取消订阅。

2)onComplete一旦延迟计算正常完成将会被调用

3)onError 一旦延迟计算抛出异常将会被调用

4.2、Completable官网图解

图解说明

1)上面一副小图的意思是:一个Completable能发射一个onError或者一个onComplete消息,该消息会被CompletableObserver的onError或者onComplete接口接收到。

2)下面大图相对复杂,涉及到是否被阻断,也就是通过Disposable调用dispose()取消订阅,后面的消息无法接收。

4.3、Completable示例

可以运行一下下面的例子,可以看到在调用dispose后,onStart被回调后,后续的消息就收不到了;去掉dispose,onStart回调后,三秒后onComplete将会被回调

 private void doCompletable() {
        Disposable d = Completable.complete()
                .delay(3, TimeUnit.SECONDS, Schedulers.io())
                .subscribeWith(new DisposableCompletableObserver() {
                    @Override
                    public void onStart() {
                        System.out.println("Started");
                    }

                    @Override
                    public void onError(Throwable error) {
                        error.printStackTrace();
                    }

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


        d.dispose();

    }

运行完毕的结果是:
10-02 11:10:34.797 15565-15565/hq.demo.net I/System.out: Started

注释d.dispose()后在运行结果是:
10-02 14:34:19.490 23232-23232/hq.demo.net I/System.out: Started
10-02 14:34:22.492 23232-23483/hq.demo.net I/System.out: Done!

上面使用的是DisposableCompletableObserver通过subscribeWith来订阅消息,返回一个Disposable可以通过dispose来取消订阅关系,DisposableCompletableObserver是CompletableObserve的子类,只是增加了可取消订阅的功能。

当然也能通过一下方法操作,但是无法取消订阅关系,除此外没什么本质区别

private void doCompletable() {
        Completable.complete()
                .delay(3, TimeUnit.SECONDS, Schedulers.io())
                .subscribe(new CompletableObserver() {


                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onError(Throwable error) {
                        error.printStackTrace();
                    }


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

    }

5、Maybe

5.1、Maybe简介

Maybe类表示延迟计算和单个值的发射,这个值可能根本没有或异常。
Maybe类实现MaybeSource的接口,MaybeObserver通过subscribe(MaybeObserver)在Maybe处订阅消息

Maybe遵循协议:onSubscribe (onSuccess | onError | onComplete),也就是Maybe发射消息后,可能会回调的接口是onSuccess | onError | onComplete

public abstract class Maybe<T> implements MaybeSource<T>
public interface MaybeSource<T> {

    /**
     * Subscribes the given MaybeObserver to this MaybeSource instance.
     * @param observer the MaybeObserver, not null
     * @throws NullPointerException if {@code observer} is null
     */
    void subscribe(MaybeObserver<? super T> observer);
}
public interface MaybeObserver<T> {
    void onSubscribe(Disposable d);
    void onSuccess(T value);
    void onError(Throwable e);
    void onComplete();
}

5.2、Maybe官方图解

5.3、Maybe示例

下面是个例子,注意让线程睡多少秒可以修改测试dispose,与Completable类似,但是无论怎么onStart()都会被回调,为什么onStart()都会被回调呢可以看DisposableMaybeObserver源码,在订阅消息的时候就会首先回调onSubscribe,这个时候dispose还没有运行了,这个动作发生在订阅的时候,没有订阅何来取消订阅呢。

public abstract class DisposableMaybeObserver<T> implements MaybeObserver<T>, Disposable {
    final AtomicReference<Disposable> s = new AtomicReference<Disposable>();

    @Override
    public final void onSubscribe(Disposable s) {
        if (DisposableHelper.setOnce(this.s, s)) {
            onStart();
        }
    }

    /**
     * Called once the single upstream Disposable is set via onSubscribe.
     */
    protected void onStart() {
    }

    @Override
    public final boolean isDisposed() {
        return s.get() == DisposableHelper.DISPOSED;
    }

    @Override
    public final void dispose() {
        DisposableHelper.dispose(s);
    }
}

下面是实例的运行和结果

private void doMaybe() {

        new Thread(new Runnable() {
            @Override
            public void run() {
                Disposable d = Maybe.just("Hello World")
                        .delay(3, TimeUnit.SECONDS, Schedulers.io())
                        .subscribeWith(new DisposableMaybeObserver<String>() {
                            @Override
                            public void onStart() {
                                System.out.println("Started");
                            }

                            @Override
                            public void onSuccess(String value) {
                                System.out.println("Success: " + value);
                            }

                            @Override
                            public void onError(Throwable error) {
                                error.printStackTrace();
                            }

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

                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                d.dispose();
            }
        }).start();

    }


运行结果是:
10-02 15:01:53.320 25573-25649/hq.demo.net I/System.out: Started
10-02 15:01:56.324 25573-25654/hq.demo.net I/System.out: Success: Hello World

如果把Thread.sleep(4000)修改为Thread.sleep(2000)运行结果是:
10-02 15:05:34.362 25840-25872/hq.demo.net I/System.out: Started

上面例子使用DisposableMaybeObserver通过subscribeWith在Maybe处订阅,并返回一个Disposable,可以通过Disposable调用dispose来取消订阅,当然我们也可以通过

下面的方式来完成,但是无法取消订阅关系

private void doMaybe() {
        Maybe.just("Hello World")
                .delay(3, TimeUnit.SECONDS, Schedulers.io())
                .subscribe(new MaybeObserver<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        System.out.println("Started");
                    }

                    @Override
                    public void onSuccess(String value) {
                        System.out.println("Success: " + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

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

    }

6、总结:

Single、Completable、Maybe是简化的Observable,只是具有少部分功能

Single:只能发射一条单一数据或者一条异常通知,不能发射完成通知,数据与通知只能发射一个,二选一。

Completable:只能发射一条完成通知或者一条异常通知,不能发射数据,要么发射完成通知要么发射异常通,二选一。

Maybe:只能发射一条单一数据,和发射一条完成通知,或者一条异常通知,完成通知和异常通知二选一,只能在发射完成通知或异常通知之前发射数据,否则发射数据无效

猜你喜欢

转载自blog.csdn.net/weixin_36709064/article/details/82911270