RxJava
来源:互联网 发布:矩阵乘法 matlab 编辑:程序博客网 时间:2024/06/11 03:54
subscribeOn()和observeOn()的区别
- subscribeOn()主要改变的是订阅的线程,即call()执行的线程;
- observeOn()主要改变的是发送的线程,即onNext()执行的线程。
总结
如果我们有一段这样的序列
Observable.map // 操作1.flatMap // 操作2.subscribeOn(io).map //操作3.flatMap //操作4.observeOn(main).map //操作5.flatMap //操作6.subscribeOn(io) //!!特别注意.subscribe(handleData)
假设这里我们是在主线程上调用这段代码,
那么
操作1
,操作2
是在io线程上,因为之后subscribeOn
切换了线程操作3
,操作4
也是在io线程上,因为在subscribeOn
切换了线程之后,并没有发生改变。操作5
,操作6
是在main线程上,因为在他们之前的observeOn
切换了线程。- 特别注意那一段,对于
操作5
和操作6
是无效的
再简单点总结就是subscribeOn
的调用切换之前的线程。observeOn
的调用切换之后的线程。observeOn
之后,不可再调用subscribeOn
切换线程
注意事项:
subscribeOn(),只有在第一次调用的时候生效,之后不管调用多少次,只会以第一次为准.
observeOn(),可以被调用多次,每次调用都会更改线程.
RxJava线程池中的几个线程选项
- Schedulers.io() io操作的线程, 通常io操作,如文件读写. - Schedulers.computation() 计算线程,适合高计算,数据量高的操作. - Schedulers.newThread() 创建一个新线程,适合子线程操作. - AndroidSchedulers.mainThread() Android的主线程,主线程
RxJava2中的常用操作符:
一:变换操作符
Map:
就是把原来的Observable对象转换成另一个Observable对象,同时将传输的数据进行一些灵活的操作,方便Observer获得想要的数据形式。
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 "我是变换过后的" + integer; } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.e("XYK",s); } });}
运行结果:
通过运行结果可以看到,我们在上游发送的数据类型为Integer,到了下游接收到的数据为String类型,中间通过map对其进行了转换,是不是感觉很强大?通过map我们可以将上游数据转化为任意类型发送到下游,就是这么6~
FlatMap:
与map类似flatmap可以将上游发送过来的数据,变换为多个数据,然后合并为一个事件发送到下游。
还是直接上代码:
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<String>(); for (int i = 0; i < 5; i++) { list.add("我是变换过的" + integer); } return Observable.fromIterable(list); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.e("XYK", s); } });}
运行结果:
图解:
通过运行结果可以看到,上游发送的数据在到达flatmap的时候,经过处理,将每个事件变成了5个,而后将5个合并为1个事件发送到下游,并且我们可以注意到,发送到下游的数据是无序的,那么这时候就要说了,我要接收的事件是有序的怎么办,这就是接下来要说的concatMap.
ConcatMap:
和FlatMap一样,只不过一个是有序,一个是无序而已,我们直接把上边的代码做一个更改:
顾名思义,过滤器,可以过滤掉一部分不符合要求的事件,如:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { for (int i = 0; i < 10000; i++) { e.onNext(i); } } }).observeOn(Schedulers.io()) .subscribeOn(AndroidSchedulers.mainThread()) .filter(new Predicate<Integer>() { @Override public boolean test(Integer integer) throws Exception { return integer % 7 == 0; } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e("XYK",integer + ""); } }); }
在上面的代码中,我们朝下游发送了10000个数据,而我只需要其中可以被7整除的数据,利用filter,将其他的数据过滤出去,留下需要的数据.
Sample,样品,其功能也是,sample会每隔一段时间对上游数据进行取样,发送到下游,但是这样会导致丢失了大量事件,比较适合特定场合,如对一组数中进行抽样,代码如下:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { for (int i = 0; ; i++) { e.onNext(i); } } }).sample(1,TimeUnit.SECONDS) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e("XYK",integer + ""); } }); }
在上边的代码中,使用sample之后,每隔1秒对上游数据采样一次,发送到下游,其他事件则被过滤.
take/takeList:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { for (int i = 0; ; i++) { e.onNext(i); } } }).take(3) //.takeLast(3) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e("XYK",integer + ""); } }); }
以将重复对象去除重复对象,这里我们要用到一个方法,repeat(),产生重复事件,这里重复事件,再去除有些多余,只作为一个例子来展示.
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { for (int i = 0;i < 50; i++) { e.onNext(i); } } }).take(3) //生成重复事件 .repeat(3) .distinct() .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e("XYK",integer + ""); } });
compose: 好用,消除重复
以上操作符是对事件进行操作,而这个操作符是对 Observable 整体的变换需要传入Observable.Transformer
.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
那么动手吧~
1.首先compose()需要传入一个Observable.Transformer类型的参数,那我们直接在这new一个即可;
2.在上述transformer对象里,我们通过重写call 方法,可以拿到一个observable对象,对其进行一系列的lift变换(自然可以切换线程);
Observable.Transformer schedulersTransformer() { return new Observable.Transformer() { @Override public Object call(Object observable) { return ((Observable) observable).subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; }
- 3.收工吃饭~
observable.compose (schedulersTransformer()).subscribe(subscriber)
doOnNext操作符
其实它不算做操作符,只是比较常用
它的作用是让订阅者在接收到数据之前干点有意思的事情。假如我们在获取到数据之前想先保存一下它,我们可以这样实现。
Observable.just(1, 2, 3, 4, 5) .doOnNext(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e(TAG, "doOnNext: 这里做一些操作就可以了"); } }) .subscribe(new Observer<Integer>() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e(TAG, "onSubscribe: "); } @Override public void onNext(@NonNull Integer integer) { Log.e(TAG, "onNext: " + integer); } @Override public void onError(@NonNull Throwable e) { Log.e(TAG, "onError: " + e); } @Override public void onComplete() { Log.e(TAG, "onComplete: "); } });
其实就是在每次发送之前先走doOnNext方法进行一些操作,它会在onNext之前调用。
参考:http://www.jianshu.com/p/c5f91b94cad8
http://www.jianshu.com/p/7c0640963bac
http://www.jianshu.com/p/8cf84f719188
- rxjava
- RXJava
- RXJava
- RXJava
- RxJava
- Rxjava
- RxJava
- RxJava
- Rxjava
- RxJava
- RxJava
- RxJava
- RxJava
- RxJava
- RxJava
- RxJava
- rxjava
- RxJava
- K&R 第二章 类型,运算符 与表达式
- Linux系统学习方法——写给小白
- Idea+Mybatis+Maven+单表增删改查
- git 拉去远程分支出错
- POJ
- RxJava
- 秒杀系统高并发优化
- Codeforces 745C Hongcow Builds A Nation
- 堆和栈的区别
- poj 1258 Agri-Net 最经典的MST★
- join,left join,right join
- 给tabBar设置图片和字体颜色 navigationBar设置字体大小 颜色
- 基于Selector+Channel+线程池的server & client
- GCC编译器中的-I -L -l 选项。