RxJava2.0笔记记录(一)
来源:互联网 发布:java压缩包文件名乱码 编辑:程序博客网 时间:2024/06/05 22:58
一 基本使用
Observable创建
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { //ObservableEmitter 发射器的意思,用来发出事件的,它可以发出三种类型的事件,通过调用emitter的onNext(T value)、onComplete()和onError(Throwable error)就可以分别发出next事件、complete事件和error事件。 } });
Observer创建
Observer<Integer> observer = new Observer<Integer>(){ @Override public void onSubscribe(Disposable d) { //开关的意思,当调用它的dispose()方法时,它就会切断事件的接受,导致观察者接受不到事件。这个可以用作当页面销毁时,取消网络请求。 } @Override public void onNext(Integer integer) { } @Override public void onError(Throwable e) { } @Override public void onComplete() { }};
订阅被观察者与观察者
observable.subscribe(observer);
一个observable可能没有观察者订阅,也可以多个观察者订阅,当观察者和被观察者建立联系后,被观察者可以通过onNext发送事件,也可以发送onComplete标志事件完成,被观察者发送onComplete之后,可以继续发送,而观察者接受到onComplete之后,就不会继续接收事件。
onComplete和onError必须唯一并且互斥。
subscribe有多个方法的重载,带有一个参数的Consumer方法,表示下游可以只关心onNext方法。
二 线程控制
默认情况下,观察者和被观察者工作在主线程。通常我们的需求是在子线程做耗时操作,然后回到主线程中来操作UI。此时我们可以用线程控制来达到这一目的。
observable .subscribeOn(Schedulers.io()) //subscribeOn被观察者工作的线程 .observeOn(AndroidSchedulers.mainThread()) //observeOn 观察者工作的线程 .subscribe(observer);
RxJava内置线程选项:
1.Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作,内部用线程池维护。
2.Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
3.Schedulers.newThread() 代表一个常规的新线程
4.AndroidSchedulers.mainThread() 代表Android的主线程
注意:
1.多次指定被观察者的线程只有第一次指定的有效, 也就是说多次调用subscribeOn() 只有第一次的有效, 其余的会被忽略.
2.多次指定观察者的线程是可以的, 也就是说每调用一次observeOn() , 下游的线程就会切换一次.
三 操作符
< 1 >.map
map是RxJava中最简单的一个变换操作符, 它的作用就是对observable发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化.
eg:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { e.onNext(1); e.onNext(2); e.onNext(3); }}).map(new Function<Integer, String>() { @Override public String apply(Integer integer) throws Exception { return "this is " + integer; }}).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { System.out.println(s); } });
通过Map可以将Observable发送的事件转换为任意的类型。
< 2 >. flatmap
FlatMap将一个发送事件的Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
eg:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { e.onNext(1); e.onNext(2); e.onNext(3); } }).flatMap(new Function<Integer, ObservableSource<String>>() { @Override public ObservableSource<String> apply(Integer integer) throws Exception { 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 { System.out.println(s); } });
注意:flatmap并不能保证事件的顺序,如果需要保证事件的顺序可以使用concatmap,用法和flatmap一样。
< 3 >.zip
zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { }}).subscribeOn(Schedulers.io());Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception { }}).subscribeOn(Schedulers.io());Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() { @Override public String apply(Integer integer, String s) throws Exception { return ""; }}).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { }});
四. 背压 Backpressure
< 1 >.原理引入
当observable和observer工作在不同线程时,它们之间不能直接通信,当observable发送一个事件时,是放在一个容器(具体就是一个队列)里面的,当容器里面有事件时,才会向observer发送事件。而当observable发送事件太快,observer取事件太慢,容器就会一直放事件,最后会因为容器事件越来越多,最后导致容器OOM了。
这种observable产生事件的速度很快,而observer处理很慢,事件会堆积起来,最终挤爆你的内存,导致程序崩溃(MissingBackpressureException异常)。
至此,就可以引出背压(Backpressure)的概念:背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略。
关于背压,可以看这里
< 2 >.解决方案
a. 使用filter过滤掉不需要的数据
b. 使用sample每隔一段时间从observable取出事件,发送给下游。
c. 延时降低observable发送事件的速度。
d.使用flowable解决。
大致就是从数量和速度上解决。
五.Flowable
这里把被观察者指定为flowable,观察者指定为subscriber。
eg:
Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() { @Override public void subscribe(FlowableEmitter<Integer> e) throws Exception { } //流速不均匀直接抛异常 }, BackpressureStrategy.ERROR); Subscriber<Integer> subscriber = new Subscriber<Integer>() { @Override public void onSubscribe(Subscription s) { } @Override public void onNext(Integer integer) { } @Override public void onError(Throwable t) { } @Override public void onComplete() { } }; flowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
和observable不同的是,这里增加了一个参数,用来处理上下游流速不均衡的时候应该怎么处理的办法,在例子中直接抛出了一个BackpressureStrategy.ERROR异常,也就是MissingBackpressureException异常。同时观察者中不是再使用Disposable,而是使用Subscription,与Disposable不同的是,这种采用的是响应式拉取,当在onSubscribe方法中调用了request方法时,observable会根据request的事件数量发相应数量的事件。observable不会再一直发事件。如果不调用request方法,在同一线程,就会抛MissingBackpressureException异常,在不同线程,observable就会先把事件放到一个容器,大小为128。当observer调用request才会发送事件。
参考
1.Season_zlc的“水管”系列
2.系列文章
- RxJava2.0笔记记录(一)
- Rxjava2.0使用笔记一
- RxJava2.0教程(一)
- RxJava2.0教程(一)
- RxJava2.0使用(一)
- Rxjava2.0教程(一)
- android RXJava2.0(一)
- RxJava2.0学习笔记(Backpressure,Flowable)
- 最简单易懂的RxJava2.0学习教程之RxJava2的基本使用(一)
- 到来的Rxjava2.0<一>
- RxJava2 基础教程(一)HelloWorld
- RxJava2 源码解析(一)
- Rxjava2源码浅析(一)
- RxJava2详解(一)--基础
- Rxjava2 源码解析(一)
- rxjava2源码笔记(二)
- 给初学者的RxJava2.0教程(一)
- 学习RxJava2.0的一些记录
- TOP100summit:【分享实录-QQ空间】10亿级直播背后的技术优化
- Java数据结构与算法解析(五)——二叉查找树
- 关于进程问题的一些思考
- cenos 7 tomcat启动巨慢的解决
- Java并发编程:volatile关键字解析
- RxJava2.0笔记记录(一)
- 【廖雪峰Python习题集】字符串和编码
- Thread的中断机制(interrupt)
- 爬虫豆瓣完整版
- c++对文件进行操作之创建特定的文件结构
- 《Spark快速大数据分析》笔记 第三章RDD编程
- shutil模块
- Java数据结构与算法解析(六)——AVL树
- smb.conf 配置