Android技能必备之RxJava

        观察者模式中除了用过EventBus外,Rxjava也是必需掌握的一个框架,本文主要介绍Rxjava的主要功能以及使用方式。

概念

       在RxJava中,函数响应式编程具体表现为一个观察者(Observer)订阅一个可观察对象(Observable),通过创建可观察对象发射数据流,经过一系列操作符(Operators)加工处理和线程调度器(Scheduler)在不同线程间的转发,最后由观察者接受并做出响应的一个过程。

Rxjava的使用

        1.引入依赖包:

 implementation "io.reactivex.rxjava2:rxjava:2.1.12"
 implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

        2.创建被观察者:

//被观察者
        Observable novel=Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<int> emitter) throws Exception {
                emitter.onNext(1);
            
                emitter.onComplete();
            }
        });

        3.创建观察者

//观察者
        Observer<String> reader=new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                mDisposable=d;
                Log.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(int value) {
               
                Log.e(TAG,"onNext:"+value);
            }

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

            @Override
            public void onComplete() {
                Log.e(TAG,"onComplete()");
            }
        };

        4.建立订阅关系

novel.subscribe(reader);

        5.链式调用:

 Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<int> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onComplete();
            }
        })
                .observeOn(AndroidSchedulers.mainThread())//回调在主线程
                .subscribeOn(Schedulers.io())//执行在io线程
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG,"onSubscribe");
                    }

                    @Override
                    public void onNext(int value) {
                        Log.e(TAG,"onNext:"+value);
                    }

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

                    @Override
                    public void onComplete() {
                        Log.e(TAG,"onComplete()");
                    }
                });

        基本的使用就是上面这些了,在链式调用的过程中,我们看到在异步的过程中使用了Schedulers,即调度器。

异步

        Rxjava的核心就是异步操作,能够在操作IO或者网络传输时使用线程池,在接收返回数据时在主线程显示。
    这里就涉及了一个名词叫Scheduler,调度器,调度器总共有五种调度方式:

  1.  Schedulers.single(): 拥有一个线程单例,所有的任务都在这一个线程中执行,当线程中有任务时,其它任务会按照先进先出的的顺序执行。
  2.  Schedulers.newThread(): 每执行一个任务创建一个新线程,不具有线程缓存机制  Scheduler.io():  用于读写SD卡文件,查询数据库,访问网络,具有线程缓存机制,调度器接收到任务后,先检查线程池中是否有空闲的线程,如果有,则复用,没有则创建新的线程,效率比newThread 高。
  3.  Schedulers.computation(): 用于CPU密集型计算任务,即不会被I/O等操作限制性能的耗时操作,比如xml.json文件解析,Bitmap图片压缩取样等,具有固定的线程池。
  4.  Schedulers.trampoline(): 在当前线程的任务立即执行,如果当前线程有任务在执行,则会将其暂停,等插进来的任务执行完之后再接着执行。
  5. AndroidSchedulers,.mainThread(): 在Android UI线程中执行任务,为Android开发定制。

subscribeOn来指定对数据的处理运行在特定的线程调度器Scheduler上,直到遇到observeOn改变线程调度器若多次设定,则只有一次起作用。observeOn指定下游操作运行在特定的线程调度器Scheduler上。若多次设定,每次均起作用。

Observer在接收到数据后,延迟了两秒才处理,但是Observable依然在Observer将数据处理完之后才开始发射下一条。Schedulers.trampoline()的作用在当前线程立即执行任务,如果当前线程有任务在执行,则会将其暂停,等插入进来的任务执行完之后,再将未完成的任务接着执行。

通过Schedulers.single()将数据的发射,处理,接收在Schedulers.single()的线程单例中排队执行,当此线程中有任务执行时,其他任务将会按照先进先出的顺序依次执行 。

 Rxjava 操作符

 操作符分以下几类:

创建:  
           1 :  create
           2 :  just :创建一个Observable,可接受一个或者多个参数
           3: fromArray:创建一个Observable,接受一个数据,并将数组逐一发送
           4: fromIterable:创建一个Observable,接受一个可迭代对象,并将可迭代对象的数据逐一发送
           5: range:创建一个Observable, 发送一个范围内的整数数据,如Observable.range(1,10)
过滤:
           filter:filter使用Predicate函数接口传入条件值,来判断每一个传入的参数是否满足条件,如果满足,则继续向下传递,不满足则过滤调。
           distinct: 过滤调重复的数据项
           链式调用,可以先用distinct过滤调重复的数据,然后再用filter筛选合适的数据
变换:
           map: 对Observable发射的每一项数据应用一个函数,执行变换操作
           map操作符,需要接收一个函数接口Function<T,R>的实例化对象,实现接口内R apply(T t)的方法,在此方法中可以对接收到的数据t进行变换后返回。
           flapmap:将一个发射数据的Observable变换为多个Observable,然后将多个Observable发射的数据合并到一个Observable中进行发射
           首先,用just操作符,发射三个数组,通过flatMap变换,将每个数组中的元素用操作符fromArray取出后逐一发射
           

组合:
            mergeWith:合并多个Observable发射的数据,可能会让Observable发射的数据交错。

            concatWith: 同mergeWith一样,用以合并多个Observable发射的数据,但是concatWith不会让Observable发射的数据交错。

聚合:
           zipWith:将多个Obversable发射的数据,通过一个函数BiFunction对对应位置的数据处理后放到一个新的Observable中发射,所发射的数据个数与最少的Observabel中的一样多。

背压策略

观察者除了observer还可以是consumer;被观察者除了observable还可以是Flowable,背压支持。那就产生了一个新的概念,背压(backpressure)什么是背压呢?按照理解是上游发射数据的速度远远大于下游,而且下游接收是一个新的线程,从而下游不会阻断上游的发送,造成上游不断新增线程,造成内存溢出。
Rxjava2相对于Rxjava1最大的更新就是把对背压问题的处理逻辑从Observable抽取出来产生了新的可观察对象Flowable。
那么Flowable可以取代Observable吗?不能,虽然Observable能解决的问题Flowable也能解决,但由于Flowable对数据加工处理的各种操作符都添加了背压支持,所以运行效率要比Observable慢得多。


Flowable和Observable的异同之处:
发射器中均有onNext,OnError,onComplete方法;
不同:1 create方法中多了一个BackpressureStrategy
              2 订阅器Subscriber中,方法onSubscribe回调的参数不是Disposable而是Subscription
              3 Flowable发射数据时,使用特有的发射器FlowableEmitter,而不同于Observable的ObservableEmitter.


BackpressureStrateqy中缓存池的上限为128,超过上限就会报这五个异常:
    MISSING   --->MissingEmitter     当超过128时,后面的
    ERROR      ---> ErrorAsyncEmitter 当超过128时,MissingBackpressureException异常。
    DROP       ---> DropAsyncEmitter 如果Flowable的异步缓存池满了,会丢掉上游发送的数据,等缓存池中数据清理之后才重新接收。
    LATEST     ---> LatestAsyncEmitter 不管缓存池的状态如何,LATEST都会将最后一条数据强行放入缓存池中
    BUFFER    ---> BufferAsyncEmitter  如果Flowable默认的异步缓存池满了,会通过此缓存池暂存数据,它与Observable的异步缓存池一样,可以无限制向里添加数据,不会抛出MissingBackpressureException异常,但会导致OOM。
通过代理对原始发射器进行了包装


如何解决背压问题?

上游e.requested能获取当前可用的线程池,只需要在数量为0时,不发射数据,当数量重新恢复时再发射;下游默认s.request(1) 默认请求数为1。

五类观察者和订阅者

ObservableSource/Observer
     可通过onNext方法发送单条数据或者数据序列,通过onComplete发送完成通知或通过onError发送异常通知,不支持背压策略。
Publisher/Subscriber
      在ObservableSource/Observer基础上进行了改进,可通过背压策略处理背压问题,但效率没有第一组高。


      以下三组是新的响应式关系的实现,在Rxjava1中没有,可看做是ObservableSource/Observer的简化版
SingleSource/SingleObserver
      不能发送数据序列或完成通知,只能通过onSuccess方法发送单条数据,或者通过onError发送异常通知
CompletableSource/CompletableObserve
      不能发送任何形式的数据(单条数据或数据序列),只能通过onComplete发送完成通知或者通过onError发送异常通知
MaybeSource/MaybeObserver
      可通过onSuccess发送单条数据,通过onComplete发送完成通知或者通过onError发送一条异常通知


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值