RxJava3 基础认识与操作

167 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

RxJava

简介

rxjava用于在 Android 上优雅的实现 异步

观察者不需要时刻盯着被观察者,而是采用注册(Register)或者称为订阅 (Subscribe) 的方式,告诉被观察者:我需要你的状态,你要在它变化的时候通知我。

操作

下面 这种写法不支持背压

当被观察者快速发送大量数据时,下游不会做其他处理,即使数据大量堆积,调用链也不会报MissingBackpressureException,消耗内存过大只会OOM

// RxJava的链式操作
        Observable.create(new ObservableOnSubscribe<Integer>() {
        // 创建被观察者
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                //在此处进行网络的请求与耗时任务的处理
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();//发出事件 
            }
        })
            .observeOn(AndroidSchedulers.mainThread())//回调在主线程
            .subscribeOn(Schedulers.io())//执行在io线程 大多数情况
            //.subscribeOn(Schedulers.newThread) 
            .subscribe(new Observer<Integer>() {
            // 2. 通过通过订阅(subscribe)连接观察者和被观察者
  
            @Override
            public void onSubscribe(Disposable d) {
                //此方法会最先被调用
                Log.d(TAG, "开始采用subscribe连接");
            }
            // 默认最先调用复写的 onSubscribe()
​
            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "对Next事件"+ value +"作出响应"  );
            }
​
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }
​
            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
​
        });
    }
}
​
注:整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.onNext()>观察者.onComplete() 
    
 observable.subscribe(observer);
// 或者:
observable.subscribe(subscriber);
​

[参阅]  www.jianshu.com/p/a406b94f3… 

在 RxJava 的默认规则中,事件的发出和消费都是在同一个线程的

在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。

Schedulers

  • Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler
  • Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io()newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • 另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。

背压

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

  1. error, 缓冲区大概在128
  2. buffer, 缓冲区在1000左右
  3. drop, 把存不下的事件丢弃
  4. latest, 只保留最新的
  5. missing, 缺省设置,不做任何操作

其他类型的观察者

  • Single/SingleObserver 只能发送单个数据

  • Completable/CompletableObserver 不发送数据,只处理 onComplete和onError事件

  • Maybe/MaybeObserver 能够发送0个或1个数据,要么成功,要么失败。

  • Flowable 支持背压

    需要通过s.request(Long.MAX_VALUE) 主动向上游请求数据(不请求默认不发送)

    获取到 s对象后, 每onNext() 后调用s.request(1);

    避免大量的数据堆积,使内存处于较低水平