1、简介
响应式编程是一种面向数据流和变化传播的编程范式。通过Rx框架我们可以很好地使用该范式。
以下为官网对该框架的解释:
ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.
It extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.
rx框架扩展了观察者模式,添加相应操作符(函数),以支持对事件序列进行处理,使你可以无需关心异步编程,线程安全,非阻塞io等技术细节。
以下为官网对该框架的解释:
ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.
It extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.
rx框架扩展了观察者模式,添加相应操作符(函数),以支持对事件序列进行处理,使你可以无需关心异步编程,线程安全,非阻塞io等技术细节。
2、基本用法
2.1 Observable
2.1.1 RxJava基于观察者模式,对其进行拓展。
Subscribers(observer,观察者)订阅事件源(Observable,被观察者)。Observables发出一系列事件,Subscribers处理这些事件。这里的事件可以是任何你感兴趣的东西(比如数据库查询,网络操作,按键事件等)
一个Observable可以发出零个或者多个事件,直到结束或者出错。每发出一个事件,就会调用它的Subscriber的onNext方法,最后调用Subscriber.onComplet()或者Subscriber.onError()结束。
另外,在没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。
通过观察者模式,我们可以在被观察者中执行网络操作等耗时的异步操作,等有结果返回时才会调用观察者的onNext方法.
一个Observable可以发出零个或者多个事件,直到结束或者出错。每发出一个事件,就会调用它的Subscriber的onNext方法,最后调用Subscriber.onComplet()或者Subscriber.onError()结束。
另外,在没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。
通过观察者模式,我们可以在被观察者中执行网络操作等耗时的异步操作,等有结果返回时才会调用观察者的onNext方法.
2.1.2 Demo
以下练习demo下载地址:http://download.csdn.net/detail/moyuxueyi/9491229
2.1.2.1 创建Observable,重写onCall方法
Observable observer = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("how");
subscriber.onNext(" are ");
subscriber.onNext("you");
subscriber.onCompleted();
}
});
Observable observalJust = Observable.just("how", " are ", "you");
Observable observalFrom = Observable.from(new String[] { "how",
" are ", "you" });
2.1.2.2 创建Subscriber ,重写onStart,onNext,onComplete,onError方法
Subscriber<String> observer = new Subscriber<String>() {
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "---onStart---");
}
@Override
public void onCompleted() {
Log.d(TAG, "---onCompleted---");
}
@Override
public void onError(Throwable arg0) {
Log.d(TAG, "---onError---");
}
@Override
public void onNext(String arg0) {
Log.d(TAG, "---onNext---" + arg0);
}
};
2.1.2.3 订阅
observalCreate.subscribe(observer);
2.1.3 小结
rxjava基于观察者模式,可以实现对任何异步操作的回调处理。可以将observable理解成一个callable对象,在observer subscribe的时候,执行了observable的call方法,在call方法中可以执行各种异步操作,执行完以后将结果回调给subscribe的onNext方法。
2.2 Operators
rxjava的核心和难点就在于其大量的操作符,可以在
http://reactivex.io/documentation/operators.html查询到所有操作符,通过这些操作符,我们可以创建observable,对observable发出的事件流进行转换,过滤事件流,合并事件流等操作。通过这些操作符,我们可以对Observable进行链式调用,直到得到我们想要传递给observer的事件。我们重点考察常用的几个操作符。
2.2.1 创建Observable
2.2.1.1 Create
见上面的例子
2.2.1.2 From
可以将一些集合等数据结构转为换事件流,在订阅时将各个item依次发送给订阅者
Observable observalArr = Observable.from(new String[] { "how", " are ","you" });
List<String> list = new ArrayList<String>();
list.add("how");
list.add("are");
list.add("you");
Observable observalList = Observable.from(list);
2.2.1.3 Just
将一系列的对象转换为事件流,在订阅时将各个item依次发送给订阅者
Observable observalJust = Observable.just("how", " are ", "you");
2.2.2 Observable转换
2.2.2.1 map
map操作符提供了对事件流的转换,以下例子为将String前面加上hello,你也可以将事件转换为任意类型。
Observable.just("hello").map(new Func1<String, String>() {
@Override
public List call(String arg0) {
return arg0+"___call";
}
}).subscribe(new Action1<String>() {
@Override
public void call(String arg0) {
Log.d(TAG,arg0);
}
});
2.2.2.2 flatmap
flatmap提供了对observable的转换
Observable.just("hello").map(new Func1<String, List<String>>() {
@Override
public List call(String arg0) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 3; i++) {
list.add(arg0 + ":" + (index++));
}
return list;
}
}).flatMap(new Func1<List<String>, Observable<String>>() {
@Override
public Observable<String> call(List<String> arg0) {
return Observable.from(arg0);
}
}).subscribe(new Action1<String>() {
@Override
public void call(String arg0) {
Log.d(TAG, "subscribe----" + arg0);
}
});
flatmap的强大之处在于在转换observable时我们可以添加包括异步操作在内的各种业务逻辑。以下载一个app为例子,我们在第一个observable中通过网络获取某个app的下载地址,获取到以后传递给第二个observable,在第二个observable中进行下载操作,下载过程中通过onnext通知observer下载进度,通过onComplete通知下载完成。如果我们要自己实现上述逻辑,则需要3级回调,堪称回调地狱,而在rxjava中通过操作符的链式调用即可实现。
2.2.2.3 buffer
聚合,将分散的事件集中为list发送给订阅者
Observable.just(1, 2, 3, 4, 5).buffer(2)//
.subscribe(new Subscriber<List<Integer>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable arg0) {
}
@Override
public void onNext(List<Integer> arg0) {
Log.d(TAG, "--" + arg0.size());
}
});
}
输出结果:2,2,1
2.2.2.4 groupBy按特定规则进行分组
Observable.just(1,2,3,4,"1","2","3",true).groupBy(new Func1<Object, String>() {
@Override
public String call(Object o) {
if (o instanceof Number) {
return "num";
} else if (o instanceof String) {
return "string";
}
return "other";
}
}).subscribe(new Subscriber<GroupedObservable<String, Object>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(GroupedObservable<String, Object> stringObjectGroupedObservable) {
Log.v(TAG,stringObjectGroupedObservable.getKey());
}
});
2.2.3 过滤事件
2.2.3.1 filter
filter可以对事件流进行过滤操作,对于符合条件的事件才继续往下传递
Observable.just(1, 2, 3, 4, 5).filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer > 3;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer num) {
Log.v(TAG, num + "");
}
});
2.2.3.2 distinct
过滤重复的事件,直接调用distinct方法即可
2.2.3.3 first
只获取第一个事件
2.2.4 合并时间流
2.2.4.1 merge
Observable odds=Observable.just(1,3,5);
Observable events=Observable.just(2,4,6);
Observable.merge(odds,events).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable arg0) {
}
@Override
public void onNext(Integer arg0) {
Log.d(TAG, "onNext :"+arg0);
}
});
结果:
03-20 11:42:52.360: D/Oserver(3681): onNext :1
03-20 11:42:52.360: D/Oserver(3681): onNext :3
03-20 11:42:52.360: D/Oserver(3681): onNext :5
03-20 11:42:52.360: D/Oserver(3681): onNext :2
03-20 11:42:52.360: D/Oserver(3681): onNext :4
03-20 11:42:52.360: D/Oserver(3681): onNext :6
2.2.5 错误处理
2.2.5.1 Retry
可以设置错误时重试策略
if a source Observable sends an onError notification, resubscribe to it in the hopes that it will complete without error
if a source Observable sends an onError notification, resubscribe to it in the hopes that it will complete without error
2.3 Schedulers
在RxAndroid中,可以通过observeOn和subscribeOn方法指定observable和observer分别工作的线程。Rx框架自动帮我们实现线程相关逻辑,无需开发者去考虑,这极大的方便了开发。
observeOn(Schedulers.newThread())
subscribeOn(AndroidSchedulers.mainThread())
如上述代码则指令被观察者在新线程中运行,观察者在主线程中运行,
2.4 rxjava+rxAndroid+retrofit 组合网络请求demo
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
apiService.getIpInfo("63.223.108.42")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<GetIpInfoResponse>() {
@Override
public void onCompleted() {
mProgressBar.setVisibility(View.GONE);
}
@Override
public void onError(Throwable e) {
mProgressBar.setVisibility(View.GONE);
mTvContent.setText(e.getMessage());
}
@Override
public void onNext(GetIpInfoResponse getIpInfoResponse) {
mTvContent.setText(getIpInfoResponse.data.country);
}
});
3 参考资料
官网:
http://reactivex.io/
http://reactivex.io/tutorials.html
https://github.com/ReactiveX/RxJava/wiki
coursera课程《响应式编程原理》:
https://www.coursera.org/course/reactive
开发技术前线:
http://www.devtf.cn/?p=770
hi大头鬼hi:
http://blog.csdn.net/lzyzsd/article/details/41833541
http://blog.csdn.net/lzyzsd/article/details/44094895
http://blog.csdn.net/lzyzsd/article/details/44891933
http://blog.csdn.net/lzyzsd/article/details/45033611
http://reactivex.io/
http://reactivex.io/tutorials.html
https://github.com/ReactiveX/RxJava/wiki
coursera课程《响应式编程原理》:
https://www.coursera.org/course/reactive
开发技术前线:
http://www.devtf.cn/?p=770
hi大头鬼hi:
http://blog.csdn.net/lzyzsd/article/details/41833541
http://blog.csdn.net/lzyzsd/article/details/44094895
http://blog.csdn.net/lzyzsd/article/details/44891933
http://blog.csdn.net/lzyzsd/article/details/45033611