RxJava2.0 初识
前言
RxJava现在已经是家喻户晓了,其里面的链式编写,可以帮助我们简化代码逻辑,提高代码阅读性。一直流行这么一句话,作为一个程序猿要学会“偷懒”,RxJava大大的提升了开发效率,和降低了后期的维护成本。不得不令人垂涎它的“魅力”。
于是,走上了学习Rxjava之路,为什么一来就用Rxjava2.0而不是最初的RxJava开始说起,原因其实是小弟之前有接触过最初的Rxjava,两者间的原理是一样的。如果是刚接触Rxjava,可以先看下下面这篇文章
http://gank.io/post/560e15be2dca930e00da1083
个人理解
RxJava以观察者模式为核心,也看过网上不少文章,在结合自己的一些看法,比较喜欢这么理解,把Flowable(2.0保留旧版本Observable)看成是数据发射源,把Subscriber(Observer)看成是数据接收源。Flowable是RxJava2.0中新增的类,它的数据接收源是Subscriber。Flowable并不是Observable的替代物,而是含有Backpressure的Observable。
Flowable 和 Observable 在2.0中的区别:
Observable 不在支持背压,而Flowable 支持非阻塞式的背压。而对于Backpressure(背压),暂时对其的理解比较模糊,在这边文章里面就先不提了,虽然我对其理解比较模糊,但是也有大牛已经对Backpressure进行了剖析,为大家提供个链接
1.基本实现
先简单的实现一个发射源和接收源,FlowableEmitter俗称为发射器,subscribe可以理解为Flowable(发射源)和Subscriber(接收源)之间的桥梁。
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> e) throws Exception {
//发射数据
e.onNext("First");
e.onNext("Second");
e.onNext("Three");
e.onComplete(); //后续发射的数据将不在接收
}
}, BackpressureStrategy.BUFFER) //背压处理
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
//一定要在这里初始化,不然接收不了发射过来的数据
}
@Override
public void onNext(String s) {
Log.e(TAG, "onNext: 接收的数据"+s);
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: 接收完成" );
}
});
再写一个2.0中保留的旧版本的Observable(发射源)和Observer(接收源)
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
//发射数据
e.onNext("1");
e.onComplete();//后续发射的数据将不在接收
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
//接收数据
Log.e(TAG, "onNext: "+s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
//接收完成
}
});
这里会发现,在新的版本中,多了一个onSubscribe();其中一个参数是Subscription ,它可以请求发射器中的数据(request),也可以释放资源(cancel)。不过需要注意:Subscription 不再有订阅subcribe和unSubcribe的概念。
另一个参数是Disposable ,它可以解除Observable与Observer间的订阅。
还可以这么创建Flowable,直接用just()发射数据(list为一个集合),请看下面:
Flowable.just(list)
.flatMap(new Function<List<String>, Publisher<Integer>>() {
@Override
public Publisher<Integer> apply(List<String> strings) throws Exception {
return Flowable.fromIterable(strings).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return s.length();
}
});
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.e(TAG, "accept: "+integer);
}
});
对于Flowable或者是Observable的创建,还有很多种方式,在文章结尾会提供Rxjava的GitHub链接出来,所有的信息都可以在里面参考。还是先来看看上面的代码,是不是发现稍微多了点新的东西,没错,下面要讲的是Rxjava之所以强大的地方,就是它的操作符。
2.操作符
<1>map,一个最简单的变换操作符,如下:
Flowable.just("1")
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return s.length();
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
}
});
Function对象中,第一个参数是发射器中传过来的数据源,第二个参数是转换后返回的数据类型,返回后的数据会发送到Consumer(直译为消费者),而Consumer类似于旧版本Rxjava中的Action1,BiConsumer类似于Action2,消费发射过来的数据。
<2>flatmap 和 concatmap
把这两个写在一起,是因为它们两个的作用几乎一模一样,小小的区别在于flatmap 变换后发射的数据不能保证是有序的,而concatmap变换后发射的数据是有序的。如下:
**flatmap**
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onNext(4);
}
},BackpressureStrategy.BUFFER)
.flatMap(new Function<Integer, Publisher<String>>() {
@Override
public Publisher<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<String>();
for (int i = 0; i <3 ; i++) {
list.add("Hello==>"+integer);
}
return Flowable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, "accept: "+s );
}
});
打印信息:
05-18 18:40:36.840 21431-21559/com.demo.mydagger E/MainActivity: accept: Hello==>1
05-18 18:40:36.840 21431-21559/com.demo.mydagger E/MainActivity: accept: Hello==>1
05-18 18:40:36.840 21431-21559/com.demo.mydagger E/MainActivity: accept: Hello==>1
05-18 18:40:36.840 21431-21560/com.demo.mydagger E/MainActivity: accept: Hello==>2
05-18 18:40:36.840 21431-21561/com.demo.mydagger E/MainActivity: accept: Hello==>3
05-18 18:40:36.840 21431-21561/com.demo.mydagger E/MainActivity: accept: Hello==>3
05-18 18:40:36.845 21431-21561/com.demo.mydagger E/MainActivity: accept: Hello==>3
05-18 18:40:36.845 21431-21560/com.demo.mydagger E/MainActivity: accept: Hello==>2
再看下concatmap
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onNext(4);
}
},BackpressureStrategy.BUFFER)
.concatMap(new Function<Integer, Publisher<String>>() {
@Override
public Publisher<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<String>();
for (int i = 0; i <3 ; i++) {
list.add("Hello==>"+integer);
}
return Flowable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, "accept: "+s );
}
});
打印信息:
05-18 18:43:17.695 24116-24293/com.demo.mydagger E/MainActivity: accept: Hello==>1
05-18 18:43:17.695 24116-24293/com.demo.mydagger E/MainActivity: accept: Hello==>1
05-18 18:43:17.695 24116-24293/com.demo.mydagger E/MainActivity: accept: Hello==>1
05-18 18:43:17.705 24116-24294/com.demo.mydagger E/MainActivity: accept: Hello==>2
05-18 18:43:17.705 24116-24294/com.demo.mydagger E/MainActivity: accept: Hello==>2
05-18 18:43:17.705 24116-24294/com.demo.mydagger E/MainActivity: accept: Hello==>2
05-18 18:43:17.715 24116-24295/com.demo.mydagger E/MainActivity: accept: Hello==>3
05-18 18:43:17.715 24116-24295/com.demo.mydagger E/MainActivity: accept: Hello==>3
05-18 18:43:17.720 24116-24295/com.demo.mydagger E/MainActivity: accept: Hello==>3
05-18 18:43:17.730 24116-24296/com.demo.mydagger E/MainActivity: accept: Hello==>4
05-18 18:43:17.730 24116-24296/com.demo.mydagger E/MainActivity: accept: Hello==>4
05-18 18:43:17.730 24116-24296/com.demo.mydagger E/MainActivity: accept: Hello==>4
这样是不是一目了然~~,再和第一个map对比,会发现,map变换是单一的,而flatmap(concatmap)转换时多个的,在发射源中发射了1 、2 、3、4是个数据源,然后在把每个数据源转换成三个时间发送到Consumer中消费,如下面草图:
其它三个数据源与此相同,就不列出来了。
这次就先简单的说下,记录下自己一个大概的初步认识,后面会慢慢的更新,写的麻麻滴,望见谅-_-。
在此给出GitHub链接