前言
相信很多小伙伴和我一样,如果一开始是从像上面这样的一个项目中接触到RxJava时是一头雾水。首先,是不懂它的用处;其次,不明白它的好处在哪里,有些看不太习惯这样很长的链式关系;
接下来我就从我的学习过程和理解来谈一下自己的了解。
要了解RxJava,首先要了解观察者模式。因为RxJava就是基于观察者模式开发的。
1. Observer观察者模式
RxJava时常与Observer观察者模式一起使用。观察者本身也就是异步机制,契合了RxJava异步的链式结构。
举一个例子,现在有某报纸报社和这些报纸的订阅读者。读者不需要时时刻刻盯着报社有没有送来报纸,而是由报社在通知读者,我们的报纸出新版,进行更新了。这便是观察者模式。
例如上面关系,一个报社可以拥有多个订阅读者;一个被观察者可以同时对应多个观察者。一般来说,创建一个观察者接口类,这样方便添加和删除观察者。观察者和被观察者都不需要关心对方的具体实现,而只需要关心接口的数据。
首先关于Observable的创建方式就有多种,常用的有
1.fromIterable()方法
Observable<String> observable = Observable.fromIterable((Iterable<String>) list);
遍历集合,发送每个item。
2.just()方法
Observable<String> observable = Observable.just("HelloWorld");`
just( )方法创建Observable,在创建Observable之后自动调用onNext( )发射数据。just中传递的参数将直接在Observer的onNext()方法中接收到。
- interval()方法
Observable.interval(10, 10, TimeUnit.SECONDS, Schedulers.trampoline())
这里的四个参数分别是: initialDelay 第一次执行的延迟时间、 period每次执行的间隔的时间、unit 时间单位、Observable对象。
创建一个按固定时间间隔发射整数序列的Observable,可用作定时器。即按照固定长时间一次调用onNext()方法。
- range( )方式
Observable<Integer> observable = Observable.range(1,10);
创建一个发射特定整数序列的Observable,第一个参数为起始值,第二个为发送的个数,如果为0则不发送,负数则抛异常。上述表示发射1到10的数。即调用10次nNext()方法,依次传入1-10数字。
- timer( )方式
Observable<Integer> observable = Observable.timer(2, TimeUnit.SECONDS);
创建一个Observable,它在一个给定的延迟后发射一个特殊的值,即表示延迟2秒后,调用onNext()方法。
2.RxJava
RxJava和Handler都是为异步机制而产生的,但是Handler是多层嵌套的结构,有时再加上一些if-else 判断,代码看起来十分不美观。不同于Handler,RxJava是链式的异步结构,在较小的简单的程序中优点并不是很明显,可以用Handler代替,但是如果是一个复杂的项目,如果使用Handler,那就要进行多次的线程调用和Handler嵌套,代码的可读性不强且十分难看。这个时候RxJava的优势就能体现出来,它的链式结构是并行调用的关系,不需要多层嵌套。
“随着程序逻辑变得越来越复杂,RxJava依然能够保持简洁"。这便是RxJava最大的优点。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onComplete();
} .subscribeOn(Schedulers.io()) // 事件执行线程
.observeOn(AndroidSchedulers.mainThread()) //指定doOnNext执行线程是主线程 事件回调线程
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "subscribe");
}
});
上面这个例子便是一个简单的观察者模式和RxJava一起使用的情况,
可以看出上面的例子是在io线程中执行,主线程进行调用。这也体现了其异步的实现。
RxJava中默认Observer (观察者)和Observer (观察者)都在同一线程执行任务。RxJava 中通过 subscribeOn 和 observeOn 两个操作符进行线程切换。
这里就不得不提到RxJava涉及到的线程切换和调度的问题。在RxJava中,线程的调度依赖于Schedulers线程切换器,切换发送和接收线程,从而实现RxJava的异步实现。
下面再举一个体现RxJava异步和线程调度的例子:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d("所在的线程:",Thread.currentThread().getName());
}
}).subscribeOn(Schedulers.io()) //使被观察者在io线程工作
.observeOn(AndroidSchedulers.mainThread()) //调度观察者在主线程工作
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("所在的线程:",Thread.currentThread().getName());
}
});
执行结果:
所在的线程:: RxCachedThreadScheduler-1
所在的线程:: main
从上面可以看到,Observable()被观察者发送消息是在io线程中进行的,而观察者仍在主线程中接收信息,以此实现了异步调度。