Android 技术扩展之RxJava

1.RxJava是什么?

Reactive Extensions(简称 ReactiveX) 是对响应式编程理念的一个实现。
它最初是由微软的一个团队所开发的响应式扩展库(Reactive Extensions libraray,Rx),随后越来流行,目前已经支持了几乎全部的流行编程语言。
RxJava是java语言的扩展库。此外还有RxPy等等

响应式编程:一种关注于数据流(data streams)和变化传递(propagation of change)的异步编程方式。
其核心思想是观察者模式,上游的数据发生变化,下游能够及时感知到这些变化。

比如:

int a = 1;
int b = a + 1;
Log.d("log" , b); // 2
a ++;
b = a + 1;
Log.d("log" , b); // 3

这种写法是很常见的命令式编程。
可以看出,我们希望b永远比a大1,但是由于语言限制,只能每次都做一次赋值。
我们就会希望存在某种方式,可以让我们只用构建一次a与b的关系,之后a的变化,不需要更多的操作b都可以知道。
这种思想就是响应式编程的思想。

2.RxJava有什么

o.png

rxjava实现响应式主要依赖四个基本接口,他们成对使用。

一个简单示例:

第一步:初始化 Observable/Flowable

Observable observable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(@NonNull ObservableEmitter e) {
                //处理网络请求或其他业务无关逻辑
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
                e.onComplete();
                e.onNext(4);
            }
        });

第二步:初始化 Observer/Subscriber

Observer observer = new Observer() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {      
            }

            @Override
            public void onNext(@NonNull Integer integer) {
                // do sth
            }

            @Override
            public void onError(@NonNull Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        }

第三步:建立订阅关系

observable.subscribe(observer);

上游(被观察者)是生产数据的,比如网络请求/调用三方库生成数据,数据产生一般来说我们的业务上不关心。
下游(观察者)是接受数据的,一般这里就是我们业务相关的处理了。比如收到网络返回的值后刷新界面等。

虽然说RxJava在android平台的实现借鉴了观察者模式。但是Observable 不保存Observer,一个Observable一次发布只能对应一个Observer,
严格上讲不是观察者模式的实现。

被观察者的比较

在最新的RxJava中提供了五种场景的被观察者的基础类,它们之间的功能和主要区别如下:
Flowable: 多个流,响应式流和背压
Observable: 多个流,无背压
Single: 只有一个元素或者错误的流
Completable: 没有任何元素,只有一个完成和错误信号的流
Maybe: 没有任何元素或者只有一个元素或者只有一个错误的流

3.RxJava可以做什么

框架的核心是在Observable的类上,基本上它的操作都可以链式调用。

1.创建操作

1. 基础创建:create 创建一个新的Observable
2. 快速创建:

  • just 快速创建被观察者对象并直接发送传入的事件(最多10个事件)
  • fromArray/fromIterable
    类似just,只不过是可变参数的方法,没有事件数限制
Observable.fromArray( 1, 2, 3, 4, 5 );
Observable.fromIterable(new ArrayList();
  • empty/error/never
    直接发送Complete事件,或onError事件,或不发送任何事件

3. 延迟创建:

  • defer:
Observable observable = Observable.defer(
(new Callable>() {
            @Override
            public ObservableSource call() {
                return Observable.create(new ObservableOnSubscribe() {
                    @Override
                    public void subscribe(ObservableEmitter emitter) {
                        Log.d(TAG, "defer subscribe:  a = " + a + " b = " + b);
                        emitter.onNext(a + b);
                    }
                });
            }
        }));
 observable.subscribe(a -> Log.d(TAG, "defer accept 1: " + a));
 observable.subscribe(a -> Log.d(TAG, "defer accept 2: " + a));

每次用户订阅的时候会创建一个新的obversable,不订阅就不创建

  • timer: 一定时间后发送一个0L
  • interval/intervalRange: 每隔指定时间就发送一个Long(从0开始每次递增1)
  • range/rangeLong:
    Observable.range(5, 10).subscribe(i -> System.out.println("1: " + i));
    产生一个从5开始的连续10个整数构成的序列

4. 重复发送:

  • repeat/repeatUntil:
Observable.fromArray(1, 2, 3, 4, 5).repeat(5)
  .subscribe(a -> Log.d(TAG, "accept create: " + a));

重复发5次12345

  • repeatWhen(Observable another)
    当另一个被观察者发射数据时,重发本观察者的数据

2.变换操作

  1. map/cast 将上游发送的数据转换成另一类数据


    map
  2. flatMap系列:上游发送一整个序列过来,逐个发送给下游


    flatmap
  3. buffer 打包操作


    buffer
  4. scan


    scan

    将相邻两个原始的结果运算后发给下游

  5. groupBy


    groupBy

3.过滤操作

  • filter


    filter
  • ofType filter的条件是类型判断
    Observable.fromArray(1, "2", 3, "w", 5).ofType(Integer.class)
  • distinct 过滤重复


    distinct
  • 其他过滤方式:除了上述根据条件过滤的方式,框架还提供了根据时间、位置过滤事件的接口

4.组合操作

  • startWith & startWithArray


    startWith
  • merge/mergeArray :合并操作
    Observable.merge(Observable.range(1,5), Observable.range(6,10)).subscribe(o)

    merge

  • concat & concatArray & concatEager :链接操作


    concat

5.其他操作

  • 线程切换:subscribeOn & observeOn
    subscribeOn 指定被观察者运行的线程
    observeOn 指定观察者接收数据的进程
    这里,库封装了线程池,对外提供线程调度器:
    • Schedulers.io():
      代表适用于io操作的调度器,增长或缩减来自适应的线程池,通常用于网络、读写文件等io密集型的操作。重点需要注意的是线程池是无限制的,大量的I/O调度操作将创建许多个线程并占用内存。
    • Schedulers.computation():
      计算工作默认的调度器,代表CPU计算密集型的操作,与I/O操作无关。它也是许多RxJava方法,比如buffer(),debounce(),delay(),interval(),sample(),skip(),的默认调度器。
    • Schedulers.newThread():代表一个常规的新线程。
    • Schedulers.immediate():
      这个调度器允许你立即在当前线程执行你指定的工作。它是timeout(),timeInterval()以及timestamp()方法默认的调度器。
    • Schedulers.trampoline():
      这个调度器有一个队列,会把任务入队延时操作。它是repeat()和retry()方法默认的调度器。
    • AndroidSchedulers.mainThread() RxAndroid库提供的用来指代Android的主线程
  • 错误处理:
    1. 超时 timeout
    2. Error处理 onErrorReturn等
    3. 重试 retry :根据得到的error重试subscribe方法

4 总结

优点

  1. 上下游处理分离,两边各自关注各自的关键逻辑,可以很好的解耦。两部分也可以由不同的开发人员同时开发。
  2. 支持背压等系列流式操作
  3. 可以和Retrofit、Gson等框架完美结合

缺点

  1. 支持的操作过多,学习成本大
  2. 小厂开发用到的开源库不多,多数场景下都是自己维护自己的架构,强行切换RxJava成本高,不一定会让结构更好
  3. Google官方推荐不适用RxJava,推荐直接使用Livedata

你可能感兴趣的:(Android 技术扩展之RxJava)