RxJava RxAndroid - 观察模式 + 异步 + 函数式

一、前言

阅读本文前,建议详细阅读并掌握什么是观察者模式

https://github.com/ReactiveX/RxJava
https://github.com/ReactiveX/RxAndroid
RxJava是ReactiveX的一种Java的实现形式,拥有三大部分

  • 观察者模式,即定义对象间一种一对多的依赖关系,当一个对象改变状态时,则所有依赖它的对象都会被改变。
  • Iterator模式,即迭代流式编程模式。
  • 函数式编程模式,即提供一系列函数样式的方法供快速开发。

首先RxAndroid基于RxJava,RxAndroid结合Android添加了很少的类,让我们在Android更方便和简单的使用RxJava。RxJava和RxAndroid已经来到了3.0+版本

RxJava核心思想:观察者模式 + 异步 来处理事件

implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'

二、基本用法

        Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
                emitter.onNext("one");
                emitter.onNext("two");
                //emitter.onComplete();
                emitter.onError(new Throwable("error"));
            }
        });
        Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d("yink","onSubscribe ...");
            }

            @Override
            public void onNext(@NonNull String s) {
                Log.d("yink","onNext = " + s);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.d("yink","onError ... = " + e);
            }

            @Override
            public void onComplete() {
                Log.d("yink","onComplete ...");
            }
        };
        observable.subscribeOn(Schedulers.newThread());
        observable.observeOn(AndroidSchedulers.mainThread());
        Log.d("yink","subscribe ...");
        observable.subscribe(observer);

首先,RxJava基于观察者模式,所以它的结构很简单,无非观察者模式三步骤:

  • Observable被观察者,ObservableEmitter为被观察者的几个事件。(onComplete和onError唯一且互斥)
  • Observer观察者,观察几个方法
  • observable.subscribe(observer)提交观察者到被观察者

其次,RxJava还额外实现了线程调度,即控制观察者和被观察者的代码在哪个线程执行:

  • observable.subscribeOn(Schedulers.newThread());设置被观察者开启新线程来调度
  • observable.observeOn(AndroidSchedulers.mainThread());设置观察者在主线程调度
    所以被观察者中我们就可以做一些耗时操作,然后ObservableEmitter通知到观察者,观察者中可以刷新UI等操作。
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: subscribe ...
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onSubscribe ...
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onNext = one
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onNext = two
2020-03-18 10:36:27.841 12678-12678/com.example.demo D/yink: onError ... = java.lang.Throwable: error

整体看来RxJava是为了让我们更加优雅的异步,异步指定线程方便,过程好控制,还可多个观察者,指定不同线程,这样异步真的太方便了。

三、详细介绍

现在我们知道RxJava大体框架,观察者模式+异步。下面我们来看详细介绍。详细介绍分为下面几个部分:

  • Observer 观察者的各种扩展写法
  • Observable 被观察者的各种拓展写法
  • 线程调度,指定线程操作相关

3.1、观察者Observer

观察者的扩展写法就比较简单

public final Disposable subscribe() 
void subscribe(@NonNull Observer<? super T> observer);
public final Disposable subscribe(@NonNull Consumer<? super T> onNext) 
public final Disposable subscribe(@NonNull Consumer<? super T> onNext, 
      @NonNull Consumer<? super Throwable> onError) 
public final Disposable subscribe(@NonNull Consumer<? super T> onNext, 
      @NonNull Consumer<? super Throwable> onError,
      @NonNull Action onComplete) 
public final Disposable subscribe(@NonNull Action onComplete) {
public final Completable doOnSubscribe(@NonNull Consumer<? super Disposable> onSubscribe) {
public final void blockingSubscribe(@NonNull Action onComplete) {
...
  • 可以看到我们提交观察者时,观察者的几个变种
  • subscribe() 实际提交的是一个Functions.emptyConsumer()
  • onNext事件:Consumer<? super T>
  • onError事件:Consumer<? super Throwable>
  • onComplete事件:Action
  • Observer<? super T> observer:多种继承自Observer的类也可以
    所以,我们在监听上,就可以简单只监听部分事件。例如
Observable.just("one").subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Throwable {

            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Throwable {
                
            }
        });

这个例子就提交了两个观察者。一个观察者只监听onNext事件,一个观察者只监听onError事件。当然你也可以只提交一个观察者。源码如下,很好理解,我随便点了一个subscribe的实现

public final Disposable subscribe(@NonNull Consumer<? super T> onNext, @NonNull Consumer<? super Throwable> onError,
           ...
        LambdaObserver<T> ls = new LambdaObserver<>(onNext, onError, onComplete, Functions.emptyConsumer());
        subscribe(ls);
        return ls;
    }

public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
            Action onComplete,
            Consumer<? super Disposable> onSubscribe) {
        super();
        this.onNext = onNext;
        this.onError = onError;
        this.onComplete = onComplete;
        this.onSubscribe = onSubscribe;
    }

@Override
    public void onNext(T t) {
        if (!isDisposed()) {
            try {
                onNext.accept(t);
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                get().dispose();
                onError(e);
            }
        }
    }

3.2、被观察者Observable

Observable是被观察者产生的地方,分下面几个方面介绍:

  • Observable的创建
  • Observable操作符归类
  • Observable扩展:Flowable、Maybe、Single、Completable

3.2.1、Observable的创建

事件产生理解上很简单,就是创建被观察者,我们以just的为例,看看它的整体思路

Observable.just("a","b").subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d("yink","onSubscribe ...");
            }

            @Override
            public void onNext(@NonNull String s) {
                Log.d("yink","onNext = " + s);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.d("yink","onError ... = " + e);
            }

            @Override
            public void onComplete() {
                Log.d("yink","onComplete ...");
            }
        });

2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onSubscribe ...
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onNext = a
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onNext = b
2020-03-24 09:30:13.562 31403-31403/com.example.demo D/yink: onComplete ...

将对象或者对象集合转换为一个会发射这些对象的Observable
just用法很简单,直接把数组以onNext事件传递,传递完后 调用onComplete事件
我们接着来看看just方法的实现,篇幅原因,我省去了一些代码。

 public static <T> Observable<T> just(@NonNull T item1, @NonNull T item2) {
        ...
        return fromArray(item1, item2);
    }

 public static <T> Observable<T> fromArray(@NonNull T... items) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableFromArray<>(items));
    }

public final class ObservableFromArray<T> extends Observable<T> {
    final T[] array;
    public ObservableFromArray(T[] array) {
        this.array = array;
    }

    @Override
    public void subscribeActual(Observer<? super T> observer) {
        FromArrayDisposable<T> d = new FromArrayDisposable<>(observer, array);

        observer.onSubscribe(d);

        if (d.fusionMode) {
            return;
        }

        d.run();
    }

    static final class FromArrayDisposable<T> extends BasicQueueDisposable<T> {
        ....
        FromArrayDisposable(Observer<? super T> actual, T[] array) {
            this.downstream = actual;
            this.array = array;
        }
        ...
        void run() {
            T[] a = array;
            int n = a.length;

            for (int i = 0; i < n && !isDisposed(); i++) {
                T value = a[i];
                if (value == null) {
                    downstream.onError(new NullPointerException("The element at index " + i + " is null"));
                    return;
                }
                downstream.onNext(value);
            }
            if (!isDisposed()) {
                downstream.onComplete();
            }
        }
    }
}
  • 可以看到调用流程也很简单,把数组挨个调用就可以了,最后发出onComplete事件
  • 事件的产生代码都极其类似,最后定位实现都会定位到类似ObservableFromArray.java这样的实现
  • 事件产生实现的代码路径在“/RxJava-3.x/src/main/java/io/reactivex/rxjava3/internal/operators/observable/**”,此路径下有很多种实现,包括from系列,just,create,error,timer等等,只是RxJava源码为我们默认添加的一些实现。
  • 创建观察者思想都类似,就不一一详述了,简单介绍如下:
用法 简单介绍
create 通过调用观察者的方法从头创建一个Observable
frome 封装Iterable、Array、Callable、Action、Runnable、Future,以执行为核心,调用封装的类型的内部事件。将其它的对象或数据结构转换为Observable
targetType.from{sourceType}()
这几种类型都是为了解决特定的问题而存在,3.1.3会简单介绍
just 将对象或者对象集合转换为一个会发射这些对象的Observable
defer 普通observable创建对象时就确定了参数,defer则是我们提交观察者时才去创建被观察者和参数,相当于一个懒加载,在观察者订阅之前不创建这个Observable,为每一个观察者创建一个新的Observable
range rang(0,10)直接生成0-10事件,创建发射指定范围的整数序列的Observable
interval interval(1, TimeUnit.SECONDS);周期性生成一个无限的、永远增长的数(长整型)
timer Observable.timer(5, TimeUnit.MINUTES)延时五分钟发送事件
empty 创建一个不发射任何数据但是正常终止的Observable,只调用一个onCompleted方法
never 创建一个什么事件都不发送的被观察者
error 发送error事件

3.2.2、ObservableObservable操作符归类

Rxjava提供的操作符真的蛮多的。主要分为下面几个大类

  • 直接创建一个Observable(创建操作)
  • 组合多个Observable(组合操作)
  • 对Observable发射的数据执行变换操作(变换操作)
  • 从Observable发射的数据中取特定的值(过滤操作)
  • 转发Observable的部分值(条件/布尔/过滤操作)
  • 对Observable发射的数据序列求值(算术/聚合操作)

这段归类描述引用自知乎的一个回答,Rxjava、rxandroid中的操作,这里我将其制成表格,供大家查阅使用,上面有创建操作符表格,所以下面是省略这部分。

变换操作

用法 简单介绍
Buffer 缓存,可以简单的理解为缓存,它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个
FlatMap 扁平映射,将Observable发射的数据变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable,可以认为是一个将嵌套的数据结构展开的过程。
GroupBy 分组,将原来的Observable分拆为Observable集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据
Map 映射,通过对序列的每一项都应用一个函数变换Observable发射的数据,实质是对序列中的每一项执行一个函数,函数的参数就是这个数据项
Scan 扫描,对Observable发射的每一项数据应用一个函数,然后按顺序依次发射这些值
Window 窗口,定期将来自Observable的数据分拆成一些Observable窗口,然后发射这些窗口,而不是每次发射一项。类似于Buffer,但Buffer发射的是数据,Window发射的是Observable,每一个Observable发射原始Observable的数据的一个子集
lift 把事件处理一次后再发送到Observer

过滤操作

用法 简单介绍
Debounce 只有在空闲了一段时间后才发射数据,通俗的说,就是如果一段时间没有操作,就执行一次操作
Distinct 去重,过滤掉重复数据项
ElementAt 取值,取特定位置的数据项
Filter 过滤,过滤掉没有通过谓词测试的数据项,只发射通过测试的
First 首项,只发射满足条件的第一条数据
IgnoreElements 忽略所有的数据,只保留终止通知(onError或onCompleted)
Last 末项,只发射最后一条数据
Sample 取样,定期发射最新的数据,等于是数据抽样,有的实现里叫ThrottleFirst
Skip 跳过前面的若干项数据
SkipLast 跳过后面的若干项数据
Take 只保留前面的若干项数据
TakeLast 只保留后面的若干项数据

组合操作

用法 简单介绍
And/Then/When 通过模式(And条件)和计划(Then次序)组合两个或多个Observable发射的数据集
CombineLatest 当两个Observables中的任何一个发射了一个数据时,通过一个指定的函数组合每个Observable发射的最新数据(一共两个数据),然后发射这个函数的结果
Join 无论何时,如果一个Observable发射了一个数据项,只要在另一个Observable发射的数据项定义的时间窗口内,就将两个Observable发射的数据合并发射
Merge 将两个Observable发射的数据组合并成一个
StartWith 在发射原来的Observable的数据序列之前,先发射一个指定的数据序列或数据项
Switch 将一个发射Observable序列的Observable转换为这样一个Observable:它逐个发射那些Observable最近发射的数据
Zip 打包,使用一个指定的函数将多个Observable发射的数据组合在一起,然后将这个函数的结果作为单项数据发射

错误处理
这些操作符用于从错误通知中恢复

用法 简单介绍
Catch 捕获,继续序列操作,将错误替换为正常的数据,从onError通知中恢复
Retry 重试,如果Observable发射了一个错误通知,重新订阅它,期待它正常终止

辅助操作

用法 简单介绍
Delay 延迟一段时间发射结果数据
Do 注册一个动作占用一些Observable的生命周期事件,相当于Mock某个操作
Materialize/Dematerialize 将发射的数据和通知都当做数据发射,或者反过来
ObserveOn 指定观察者观察Observable的调度程序(工作线程)
Serialize 强制Observable按次序发射数据并且功能是有效的
Subscribe 收到Observable发射的数据和通知后执行的操作
SubscribeOn 指定Observable应该在哪个调度程序上执行
TimeInterval 将一个Observable转换为发射两个数据之间所耗费时间的Observable
Timeout 添加超时机制,如果过了指定的一段时间没有发射数据,就发射一个错误通知
Timestamp 给Observable发射的每个数据项添加一个时间戳
Using 创建一个只在Observable的生命周期内存在的一次性资源

条件和布尔操作

用法 简单介绍
All 判断Observable发射的所有的数据项是否都满足某个条件
Amb 给定多个Observable,只让第一个发射数据的Observable发射全部数据
Contains 判断Observable是否会发射一个指定的数据项
DefaultIfEmpty 发射来自原始Observable的数据,如果原始Observable没有发射数据,就发射一个默认数据
SequenceEqual 判断两个Observable是否按相同的数据序列
SkipUntil 丢弃原始Observable发射的数据,直到第二个Observable发射了一个数据,然后发射原始Observable的剩余数据
SkipWhile 丢弃原始Observable发射的数据,直到一个特定的条件为假,然后发射原始Observable剩余的数据
TakeUntil 发射来自原始Observable的数据,直到第二个Observable发射了一个数据或一个通知
TakeWhile 发射原始Observable的数据,直到一个特定的条件为真,然后跳过剩余的数据

算术和聚合操作

用法 简单介绍
Average 计算Observable发射的数据序列的平均值,然后发射这个结果
Concat 不交错的连接多个Observable的数据
Count 计算Observable发射的数据个数,然后发射这个结果
Max 计算并发射数据序列的最大值
Min 计算并发射数据序列的最小值
Reduce 按顺序对数据序列的每一个应用某个函数,然后返回这个值
Sum 计算并发射数据序列的和

连接操作

用法 简单介绍
Connect 指示一个可连接的Observable开始发射数据给订阅者
Publish 将一个普通的Observable转换为可连接的
RefCount 使一个可连接的Observable表现得像一个普通的Observable
Replay 确保所有的观察者收到同样的数据序列,即使他们在Observable开始发射数据之后才订阅

转换操作

用法 简单介绍
To 将Observable转换为其它的对象或数据结构
Blocking 阻塞Observable的操作符

这几个表格的目的是方便大家查阅,我们不需要一口气学习所有操作符,知其思想即可。这些操作符目的加工Observable
由于篇幅原因这里只举一个map例子,上面所有操作符都很容易上手使用,就不过多阐述。

Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
        }
    }).map(new Function<Integer, String>() {
        @Override
        public String apply(Integer integer) throws Exception {
            return "map add " + integer;
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.d("yink", s);
        }
    });

2020-03-24 14:59:30.518 8467-8467/com.example.demo D/yink: map add 1
2020-03-24 14:59:30.518 8467-8467/com.example.demo D/yink: map add 2
2020-03-24 14:59:30.518 8467-8467/com.example.demo D/yink: map add 3

自定义操作符
自定义操作符有两个方向:

  • 对Observable被观察者中的数据动刀,让数据转换一次,最后再发送到观察者。
  • 对Observable被观察者直接动刀,转换一次被观察者
    1、实现ObservableOperator接口,转换数据
@FunctionalInterface
public interface ObservableOperator<@NonNull Downstream, @NonNull Upstream> {
    @NonNull
    Observer<? super Upstream> apply(@NonNull Observer<? super Downstream> observer) throws Throwable;
}

Observable.just("1","2")
                  .lift(new YourClass<String>())

2、实现ObservableOperator

public interface ObservableTransformer<Upstream, Downstream> {
    @NonNull
    ObservableSource<Downstream> apply(@NonNull Observable<Upstream> upstream);
}

Observable.just("1","2")
                  .compose(new YourTransformer())
                  .subscribe...

3.2.3、Observable扩展

Flowable、Maybe、Single、Completable

Flowable
Flowable为了解决背压的问题而存在。直接上例子:

Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> e) throws Exception {
                for(int j = 0; j <= 100; j++){
                    e.onNext(j);
                    Log.i("yink"," send id = " + j);
                    try{
                        Thread.sleep(50);
                    }catch (Exception ex){
                    }
                }
            }
        }, BackpressureStrategy.MISSING)
                .subscribeOn(Schedulers.newThread())
                .observeOn(Schedulers.newThread())
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE); //观察者设置接收事件的数量,如果不设置接收不到事件
                    }
                    @Override
                    public void onNext(Integer integer) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.e("yink","onNext = " + integer);
                    }
                    @Override
                    public void onError(Throwable t) {
                        Log.e("yink","onError = " + t.toString());
                    }
                    @Override
                    public void onComplete() {
                        Log.e("yink","onComplete");
                    }
                });
  • 背压:被观察者发送事件的速度大于观察者接收的速度时,观察者内部是创建一个无限大的缓存来暂存没有处理的事件。如果事件太多会导致OOM。
  • Flowable提供了几种方式来避免无限放大的缓存
  • Flowable 在使用上并无太大差别,多了一个BackpressureStrategy参数,必须指定接收事件数量
  • Flowable 缓存池默认大小是128
  • BackpressureStrategy参数就是Flowable设置在背压发生时处理的方式,参数类型如下:
public enum BackpressureStrategy {
    MISSING,
    ERROR,
    BUFFER,
    DROP,
    LATEST
}
类型 简单介绍
MISSING 不采取任何背压策略(既不丢弃,也不缓存),超出队列大小会抛出onError事件,不影响事件发送,抛出MissingBackpressureException: Queue is full?!
ERROR 万一下游跟不上,抛出MissingBackpressureException: create: could not emit value due to lack of requests
BUFFER 缓存所有
DROP 下游处理跟不上,删除最新
LATEST 下游处理跟不上,只保留最新

Single
Single,用法如其名,它只有onSuccess和onError事件,只发送一次事件。例子如下比较简单:

      Single.create(new SingleOnSubscribe<String>() {

            @Override
            public void subscribe(@NonNull SingleEmitter<String> e) throws Exception {

                e.onSuccess("1");
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                Log.d("yink","s = " + s.toString());
            }
        });

public interface SingleEmitter<@NonNull T> {
    void onSuccess(@NonNull T t);
    void onError(@NonNull Throwable t);
    void setDisposable(@Nullable Disposable d);
    void setCancellable(@Nullable Cancellable c);
    boolean isDisposed();
    boolean tryOnError(@NonNull Throwable t);
}

Completable
Completable不发送任何数据,发送onComplete和onError,用法也比较简单,下面例子就是,线程执行完了,接着可以做别的。因为线程执行时也不用发出什么事件,或者发送值。
Completable还支持toXXX,转换成Flowable/Single/Maybe/Observable

Completable.create(new CompletableOnSubscribe() {
            @Override
            public void subscribe(@NonNull CompletableEmitter emitter) throws Exception {
                try{
                        Thread.sleep(50);
                    }catch (Exception ex){
                    }
            }
        }).andThen(Observable.range(1, 10))
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                Log.d("yink","integer = " + integer);
            }
        });

public interface CompletableEmitter {
    void onComplete();
    void onError(@NonNull Throwable t);
    void setDisposable(@Nullable Disposable d);
    void setCancellable(@Nullable Cancellable c);
    boolean isDisposed();
}

Maybe
Maybe可以理解为Single和Completable的结合。看事件就理解了,Maybe只能传一次值onSuccess,然后支持onComplete和onError事件。

      Maybe.create(new MaybeOnSubscribe<String>() {

            @Override
            public void subscribe(@NonNull MaybeEmitter<String> e) throws Exception {
                e.onSuccess("testA");
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                Log.d("yink", " s = " + s);
            }
        });

public interface MaybeEmitter<@NonNull T> {
    void onSuccess(@NonNull T t);
    void onError(@NonNull Throwable t);
    void onComplete();
    void setDisposable(@Nullable Disposable d);
    void setCancellable(@Nullable Cancellable c);
    boolean isDisposed();
    boolean tryOnError(@NonNull Throwable t);
}

所以Rxjava提供五种被观察者写法:Observable、Flowable、Maybe、Single、Completable。可以方便我们再合适的地方用合适的类,写出更优美的代码。

3.3、线程调度

此小结为RxJava最骚的地方,正是因为RxJava在观察者模式上增加了线程调度,所以让异步变得如此优美。

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
                Log.e("yink", "Observable call: " + Thread.currentThread().getName());
                emitter.onNext("one");
                emitter.onNext("two");
            }
        })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Throwable {
                Log.e("yink", "Observer call: " + Thread.currentThread().getName());
                Log.d("yink","s = " + s);
            }
        });

2020-03-25 09:31:38.388 29612-29724/com.example.demo E/yink: Observable call: RxNewThreadScheduler-1
2020-03-25 09:31:38.417 29612-29612/com.example.demo E/yink: Observer call: main
2020-03-25 09:31:38.417 29612-29612/com.example.demo D/yink: s = one
2020-03-25 09:31:38.417 29612-29612/com.example.demo E/yink: Observer call: main
2020-03-25 09:31:38.417 29612-29612/com.example.demo D/yink: s = two
方法 简单介绍
Schedulers.io() 用于IO密集型的操作,线程缓存(有空闲则复用,否则无限增加)
Schedulers.newThread() 每次创建一个新线程,不具有缓存
Schedulers.single() 单线程,先进先出
Schedulers.computation() cpu密集型计算任务,具有固定的线程池,大小为CPU核数,不可以用于IO操作,因为IO操作的等待时间会浪费cpu
Schedulers.trampoline() 立即执行当前添加任务A,若有一个B任务正在执行,则暂停B,执行完A后再接着执行B
Schedulers.from(Executor) 提供带入线程池的方式
AndroidSchedulers.mainThread() RxAndroid扩展,Android中UI线程中执行
AndroidSchedulers.from(Looper) RxAndroid扩展,Looper当前循环线程执行

RxJava/RxAndroid默认给我们线程调度方式基本涵盖了我们绝大部分会使用的情况。

四、RxAndroid

RxAndroid中的代码很少,它扩展的意义在于方便我们结合Android特性,在UI线程中调度。或者结合Handler调度。举两个例子

public class ReactiveFragment extends Fragment {//在UI线程中的例子
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Observable.just("one", "two", "three", "four", "five")
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(/* an Observer */);
    }

new Thread(new Runnable() {//在其他线程中的例子
    @Override
    public void run() {
        final Handler handler = new Handler(); //绑定到这个线程的Handler
        Observable.just("one", "two", "three", "four", "five")
                .subscribeOn(Schedulers.newThread())
                .observeOn(HandlerScheduler.from(handler))
                .subscribe(/* an Observer */)
    }
}, "custom-thread-1").start();

五、写在最后

到此RxJava和RxAndroid介绍的差不多了。本文主要目的是全方位的介绍一下RxJava,主要拆分成:被观察者 + 观察者 + 异步,分部分来讲解。来达到对RxJava有一个整体上,不光是用法,还有思想上的理解。希望本文对你有所帮助。有啥对或者不对的地方,欢迎交流,指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容