RxJava的应用场景
我认为“RxJava的应用场景到底在哪里?”的答案,应该到“什么是Rx”里找?先弄清楚“什么是Rx”,然后再思考RxJava可以给我们的项目带来什么好处?
Rx是什么:Rx是一个基于响应式编程思想实现的函数库,让开发者可以利用可观察序列和LINQ风格查询操作符来编写异步和基于事件的程序(可以这样定义:Rx=Observable + LINQ + Schedule)
因此,RxJava的应用场景其实应该从其特点(Observable-事件,LINQ-链式操作符,Schedule-线程,响应式编程)出发。能够发挥其特点帮助开发者更快速高效的进行开发的场景,就是RxJava的应用场景。
- 项目中,存在大量复杂的操作(包括UI反馈,网络请求等)。这些操作会引出一连串业务处理(包括UI刷新,DB处理等),通过RxJava将操作转化为Observable,再通过响应式编程链式调用来实现业务,可以让业务处理的流程更加清楚,改动业务更灵活。
- RxJava提供了大量操作事件的操作符,这些操作符的功能涵盖了项目开发中大部分的应用场景,使用这些操作符API,可以减少开发成本,事半功倍。
- RxJava提供了方便的线程切换操作,切换线程不再需要用到Handler之类的操作了。加大开发效率,提升代码清晰度。
Observable使用介绍
- Observable为上游操作,负责发送事件
- Observer为下游操作,负责接收事件
同步调用示例
//创建一个上游 Observable:
Observable<Integer> observable = 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();
}
});
//创建一个下游 Observer
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "subscribe");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "error");
}
@Override
public void onComplete() {
Log.d(TAG, "complete");
}
};
//建立连接
observable.subscribe(observer);
/*
打印信息:
04-24 21:31:10.412 20629-20629/example.abe.com.android.frameworkgit D/VolleyBaseActivity: subscribe
04-24 21:31:10.412 20629-20629/example.abe.com.android.frameworkgit D/VolleyBaseActivity: 1
04-24 21:31:10.412 20629-20629/example.abe.com.android.frameworkgit D/VolleyBaseActivity: 2
04-24 21:31:10.412 20629-20629/example.abe.com.android.frameworkgit D/VolleyBaseActivity: 3
04-24 21:31:10.412 20629-20629/example.abe.com.android.frameworkgit D/VolleyBaseActivity: complete
*/
参数介绍
ObservableEmitter参数用来发出事件的发射器,它可以发出三种类型的事件,通过onNext(T value)发送next事件、通过onComplete()发送complete事件和通过onError(Throwable error)发送error事件
- onNext()方法:上游可以发送无限个onNext, 下游也可以接收无限个onNext。
- onCompute()方法:当上游发送了一个onComplete后, 上游onComplete之后的事件将会继续发送, 而下游收到onComplete事件之后将不再继续接收事件。
- onError()方法:当上游发送了一个onError后, 上游onError之后的事件将继续发送, 而下游收到onError事件之后将不再继续
- 注意点:最为关键的是onComplete和onError必须唯一并且互斥, 即不能发多个onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError, 反之亦然
连接上游和下游的一个开关,当调用它的dispose()方法时, 它就会将两根管道切断, 从而导致下游收不到事件.注意: 调用dispose()并不会导致上游不再继续发送事件, 上游会继续发送剩余的事件。
异步调用示例
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "Observable thread is : " + Thread.currentThread().getName());
Log.d(TAG, "emit 1");
emitter.onNext(1);
}
});
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
Log.d(TAG, "onNext: " + integer);
}
};
observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(consumer);
/**
打印信息:
04-24 21:55:51.466 21858-21912/example.abe.com.android.frameworkgit D/VolleyBaseActivity: Observable thread is : RxCachedThreadScheduler-1
04-24 21:55:51.466 21858-21912/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 1
04-24 21:55:51.485 21858-21858/example.abe.com.android.frameworkgit D/VolleyBaseActivity: Observer thread is :main
04-24 21:55:51.485 21858-21858/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 1
*/
RxJava线程切换操作
Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
Schedulers.newThread() 代表一个常规的新线程
AndroidSchedulers.mainThread() 代表Android的主线程
Flowable使用介绍
- Flowable为上游操作,负责发送事件,与Observable的区别在于Flowable提供背压策略,方便使用。
- Subscriber为下游操作,负责接收事件。
- BackpressureStrategy.ERROR:缓存区默人大小128,流速不均衡时发射MissingBackpressureException信号。
- BackpressureStrategy.BUFFER:缓存区不限制大小,使用不当仍会OOM。
- BackpressureStrategy.DROP:缓存最近的nNext事件。
- BackpressureStrategy.LATEST:缓存区会保留最后的OnNext事件,覆盖之前缓存的OnNext事件。
- BackpressureStrategy.MISSING:OnNext事件没有任何缓存和丢弃,下游要处理任何溢出。
同步操作
Flowable<Integer> upstream = Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emit 1");
emitter.onNext(1);
Log.d(TAG, "emit 2");
emitter.onNext(2);
Log.d(TAG, "emit 3");
emitter.onNext(3);
Log.d(TAG, "emit complete");
emitter.onComplete();
}
}, BackpressureStrategy.ERROR); //增加了一个参数,提供背压策略
Subscriber<Integer> downstream = new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.d(TAG, "onSubscribe");
s.request(Long.MAX_VALUE); //设置获取上游请求数量
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable t) {
Log.w(TAG, "onError: ", t);
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
upstream.subscribe(downstream);
/**
打印信息:
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onSubscribe
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 1
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 1
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 2
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 2
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 3
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 3
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit complete
04-25 19:25:13.453 1754-1754/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onComplete
*/
异步操作
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emit 1");
emitter.onNext(1);
Log.d(TAG, "emit 2");
emitter.onNext(2);
Log.d(TAG, "emit 3");
emitter.onNext(3);
Log.d(TAG, "emit complete");
emitter.onComplete();
}
}, BackpressureStrategy.ERROR).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.d(TAG, "onSubscribe");
s.request(3); //把Subscription保存起来
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable t) {
Log.w(TAG, "onError: ", t);
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
/**
打印信息:
04-25 19:29:58.530 2639-2639/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onSubscribe
04-25 19:29:58.531 2639-2697/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 1
04-25 19:29:58.532 2639-2697/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 2
04-25 19:29:58.532 2639-2697/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 3
04-25 19:29:58.532 2639-2697/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit complete
04-25 19:29:58.545 2639-2639/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 1
04-25 19:29:58.545 2639-2639/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 2
04-25 19:29:58.545 2639-2639/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 3
04-25 19:29:58.545 2639-2639/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onComplete
*/
Map操作符介绍
Map是RxJava中最简单的一个变换操作符了, 它的作用就是对上游发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化. 用事件图表示为:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "This is result " + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
/*
打印信息:
04-24 22:15:21.136 22309-22309/example.abe.com.android.frameworkgit D/VolleyBaseActivity: This is result 1
04-24 22:15:21.136 22309-22309/example.abe.com.android.frameworkgit D/VolleyBaseActivity: This is result 2
04-24 22:15:21.136 22309-22309/example.abe.com.android.frameworkgit D/VolleyBaseActivity: This is result 3
*/
FlatMap操作符介绍
FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里,时间无序。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
//上游发送3个事件
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
//将1个事件转变为发送3个事件,并延迟10毫秒发送
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("I am value " + integer);
}
return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
/**
打印信息:
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 2
*/
ConcatMap操作符介绍
ConcatMap和FlatMap的作用是一样的,唯一区别是concatMap是时间有序的。用法和FlatMap一样。如下所示:Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).concatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("I am value " + integer);
}
return Observable.fromIterable(list).delay(10,TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, s);
}
});
/**
打印信息:
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 3
*/
Zip操作符介绍
zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emit 1");
emitter.onNext(1);
Thread.sleep(1000);
Log.d(TAG, "emit 2");
emitter.onNext(2);
Thread.sleep(1000);
Log.d(TAG, "emit 3");
emitter.onNext(3);
Thread.sleep(1000);
Log.d(TAG, "emit 4");
emitter.onNext(4);
Thread.sleep(1000);
Log.d(TAG, "emit complete1");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());//切换线程,主要是为了体现异步有序的特点
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "emit A");
emitter.onNext("A");
Thread.sleep(1000);
Log.d(TAG, "emit B");
emitter.onNext("B");
Thread.sleep(1000);
Log.d(TAG, "emit C");
emitter.onNext("C");
Thread.sleep(1000);
Log.d(TAG, "emit complete2");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io());//切换线程,主要是为了体现异步有序的特点
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(String value) {
Log.d(TAG, "onNext: " + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
/**
打印信息:
04-25 18:49:46.294 31115-31115/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onSubscribe
04-25 18:49:46.295 31115-31156/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 1
04-25 18:49:46.295 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit A
04-25 18:49:46.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 1A
04-25 18:49:47.296 31115-31156/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 2
04-25 18:49:47.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit B
04-25 18:49:47.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 2B
04-25 18:49:48.296 31115-31156/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 3
04-25 18:49:48.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit C
04-25 18:49:48.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onNext: 3C
04-25 18:49:49.296 31115-31156/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit 4
04-25 18:49:49.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: emit complete2
04-25 18:49:49.296 31115-31157/example.abe.com.android.frameworkgit D/VolleyBaseActivity: onComplete
*/
参考
给初学者的RxJava2.0教程(一):http://www.jianshu.com/p/464fa025229e给初学者的RxJava2.0教程(二):http://www.jianshu.com/p/8818b98c44e2
给初学者的RxJava2.0教程(三):http://www.jianshu.com/p/128e662906af
给初学者的RxJava2.0教程(四):http://www.jianshu.com/p/bb58571cdb64
给初学者的RxJava2.0教程(五):http://www.jianshu.com/p/0f2d6c2387c9
给初学者的RxJava2.0教程(六):http://www.jianshu.com/p/e4c6d7989356
给初学者的RxJava2.0教程(七):http://www.jianshu.com/p/9b1304435564
给初学者的RxJava2.0教程(八):http://www.jianshu.com/p/a75ecf461e02
给初学者的RxJava2.0教程(九):http://www.jianshu.com/p/36e0f7f43a51