持续创作,加速成长!这是我参与「掘金日新计划 · 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 主线程运行。
背压
背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略 背压策略:
- error, 缓冲区大概在128
- buffer, 缓冲区在1000左右
- drop, 把存不下的事件丢弃
- latest, 只保留最新的
- missing, 缺省设置,不做任何操作
其他类型的观察者
-
Single/SingleObserver 只能发送单个数据
-
Completable/CompletableObserver 不发送数据,只处理 onComplete和onError事件
-
Maybe/MaybeObserver 能够发送0个或1个数据,要么成功,要么失败。
-
Flowable 支持背压
需要通过s.request(Long.MAX_VALUE) 主动向上游请求数据(不请求默认不发送)
获取到 s对象后, 每onNext() 后调用s.request(1);
避免大量的数据堆积,使内存处于较低水平