# RxJava #
- 观察者observer和被观察者Observable
//被观察者的创建
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
//emitter是一个发射器,可以调用onNext(),onComplete(),onError(),后面这两个事件是唯一的,只能存在一个,不能发送多个onComplete()和多个onError()和两者都存在
//调用onNext()会依次的发送该数据,当调用onComplete()的时候如果后面还有onNext(),依然
//会发送,但是下面observer也会一次接收这些数据,当接收到onComplete()事件时,就不再接收了
emitter.onNext("我");
emitter.onNext("不");
emitter.onNext("知");
emitter.onNext("道");
emitter.onComplete();
Log.e("qiukailong","还发送吗?");
emitter.onNext("这");
emitter.onNext("是");
emitter.onNext("什");
emitter.onNext("么");
Log.e("qiukailong","发送完成");
}
});
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
//当在onNext()调用d.dispose()后,将不再接收所发送的事件,但是emitter依然会发送未发送完的事件
}
@Override
public void onNext(String value) {
Log.e("qiukailong",value);
mTv.setText(value); //这个使用textview显示文字的时候只会显示最后一个接收到的,因为把之前的给替换了
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e("qiukailong","complete");
}
};
observable.subscribe(observer); //在这里订阅,只有订阅了才会发送数据,所以订阅的时候就可以写成链式的
- 打印结果
! [](http://i.imgur.com/wIdUagS.png)
! [](http://i.imgur.com/iL1V9hq.png)
- subscribe()有多个重载的方法:
- 不带任何参数的subscribe(),不管发送什么都不接收
- 带有一个Consumer参数的方法表示observer只关心onNext事件, 其他的事件不接收, 因此如果只需要onNext事件可以这么使用这个
- 以上的是在同一个线程中发送和接收数据,一般会有耗时联网等的操作然后再更新UI,耗时的要在子线程中进行,更新UI就要在主线程中了,所以就可以用RxJava内置的线程调度器
/*
* subscribeOn()可以调用多次,但是只有第一次有效
* observeOn()可以调用多次,每调用一次就会切换一次
* 这是指定发送事件所在的线程
* Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
* Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
* Schedulers.newThread() 代表一个常规的新线程
* AndroidSchedulers.mainThread() 代表Android的主线程
* */
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
- 如果在请求的过程中Activity已经退出了,这个时候如果回到主线程去更新UI,那么APP肯定就崩溃了,Disposable是个开关,调用它的dispose()方法时就会不再接收事件,既然收不到事件,那么也就不会再去更新UI了,因此可以在Activity中将这个Disposable保存起来,当Activity退出时,切断它即可.
- 如果有多个Disposable,RxJava中已经内置了一个容器CompositeDisposable,每当我们得到一个Disposable时就调用CompositeDisposable.add()将它添加到容器中,在退出的时候,调用CompositeDisposable.clear()即可切断所有的接收事件.
- 网络或者数据库操作时候就在Observable中操作,订阅的时候设置发送数据的线程为子线程
- 如果发送的数据类型不是我们要接收的类型,比如发送的是int类型,我们想要String类型的,就可以通过map,map是RxJava中最简单的一个变换操作符了, 它的作用就是对上游发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化.
! [](http://i.imgur.com/hcB5ilf.png)
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "Rxjava" + integer; //这就是要发送的数据,int
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Toast.makeText(MainActivity.this, "看这里" + s, Toast.LENGTH_LONG).show(); //String
}
});
- FlatMap flatMap是一个非常强大的操作符,FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
! [](http://i.imgur.com/g3bHNLv.png)
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
}
}).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("我 是 =" + integer);
}
return Observable.fromIterable(list).delay(10 , TimeUnit.SECONDS);//延时
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e("qiukailong", s);
}
});
- 打印结果
! [](http://i.imgur.com/IfJSrss.png)
- 使用flatmap,flatMap并不保证事件的顺序,如果需要保证顺序则需要使用concatMap.把上面的flatmap换成concatMap就可以了,打印结果
! [](http://i.imgur.com/dTcFSjx.png)
- zip操作符,Zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
! [](http://i.imgur.com/Yt0naZ3.png)
- 创建两个Observable,在不同的线程中发送事件
final Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.e("qiukailong", "1");
emitter.onNext(2);
Log.e("qiukailong", "2");
emitter.onNext(3);
Log.e("qiukailong", "3");
emitter.onNext(4);
Log.e("qiukailong", "4");
}
}).subscribeOn(Schedulers.io()); //在子线程中
final Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("A");
Log.e("qiukailong", "A");
emitter.onNext("B");
Log.e("qiukailong", "B");
emitter.onNext("C");
Log.e("qiukailong", "C");
emitter.onComplete();
emitter.onNext("D");
Log.e("qiukailong", "D");
}
}).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.e("qiukailong", "onSubscribe");
}
@Override
public void onNext(String value) {
Log.e("qiukailong", value);
}
@Override
public void onError(Throwable e) {
Log.e("qiukailong", "onError");
}
@Override
public void onComplete() {
Log.e("qiukailong", "onComplete");
}
});
- 打印结果
! [](http://i.imgur.com/nf0QX0Q.png)
- 使用zip时,Observable1和Observable2发送数据,如果Observable1发送快,而Observable2发送慢,Observable1的事件会存储到某个地方,但是如果事件过多就会导致omm,因为存储的数据太多,其他情况发送和接收事异步的话也会出现oom
- 还有filter操作符,过滤掉自己不想要的
- sample操作符,设定每隔指定时间从发送事件那里取出事件
- Flowable和Subscriber
final Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
//flowable中有大小为128的储存器,如果subscribe没有 s.request(Long.MAX_VALUE)写这个,就会把要发送的事件储存起
//来,如果通过外部调用的 s.request(Long.MAX_VALUE)时候指定数量,依然可以取出事件
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.e("qiukailong","1");
emitter.onNext(2);
Log.e("qiukailong", "2");
emitter.onNext(3);
Log.e("qiukailong", "3");
}
}, BackpressureStrategy.ERROR); //BackpressureStrategy.BUFFER没有大小限制超过128也没事
//BackpressureStrategy.DROP 把存不下的事件丢弃
//BackpressureStrategy.LATEST只保留最新的事件
Subscriber<Integer> subscriber = new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.e("qiukailong", "onSubscribe");
//如果不想接收事件就调用s.cancel();
s.request(Long.MAX_VALUE); //代表能处理多少事件,如果发送事件大于这个处理数量,就会抛出
// onErrorio.reactivex.exceptions.MissingBackpressureException: create: could not emit value due to lack of requests
}
@Override
public void onNext(Integer integer) {
Log.e("qiukailong", integer + "");
}
@Override
public void onError(Throwable t) {
Log.e("qiukailong", "onError" + t);
}
@Override
public void onComplete() {
Log.e("qiukailong", "onComplete");
}
};
flowable.subscribe(subscriber);
//当接收和发送在同意线程中,可以通过emitter.requested()获取接收事件的数量
- 观察者observer和被观察者Observable
//被观察者的创建
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
//emitter是一个发射器,可以调用onNext(),onComplete(),onError(),后面这两个事件是唯一的,只能存在一个,不能发送多个onComplete()和多个onError()和两者都存在
//调用onNext()会依次的发送该数据,当调用onComplete()的时候如果后面还有onNext(),依然
//会发送,但是下面observer也会一次接收这些数据,当接收到onComplete()事件时,就不再接收了
emitter.onNext("我");
emitter.onNext("不");
emitter.onNext("知");
emitter.onNext("道");
emitter.onComplete();
Log.e("qiukailong","还发送吗?");
emitter.onNext("这");
emitter.onNext("是");
emitter.onNext("什");
emitter.onNext("么");
Log.e("qiukailong","发送完成");
}
});
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
//当在onNext()调用d.dispose()后,将不再接收所发送的事件,但是emitter依然会发送未发送完的事件
}
@Override
public void onNext(String value) {
Log.e("qiukailong",value);
mTv.setText(value); //这个使用textview显示文字的时候只会显示最后一个接收到的,因为把之前的给替换了
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e("qiukailong","complete");
}
};
observable.subscribe(observer); //在这里订阅,只有订阅了才会发送数据,所以订阅的时候就可以写成链式的
- 打印结果
! [](http://i.imgur.com/wIdUagS.png)
! [](http://i.imgur.com/iL1V9hq.png)
- subscribe()有多个重载的方法:
- 不带任何参数的subscribe(),不管发送什么都不接收
- 带有一个Consumer参数的方法表示observer只关心onNext事件, 其他的事件不接收, 因此如果只需要onNext事件可以这么使用这个
- 以上的是在同一个线程中发送和接收数据,一般会有耗时联网等的操作然后再更新UI,耗时的要在子线程中进行,更新UI就要在主线程中了,所以就可以用RxJava内置的线程调度器
/*
* subscribeOn()可以调用多次,但是只有第一次有效
* observeOn()可以调用多次,每调用一次就会切换一次
* 这是指定发送事件所在的线程
* Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
* Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
* Schedulers.newThread() 代表一个常规的新线程
* AndroidSchedulers.mainThread() 代表Android的主线程
* */
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
- 如果在请求的过程中Activity已经退出了,这个时候如果回到主线程去更新UI,那么APP肯定就崩溃了,Disposable是个开关,调用它的dispose()方法时就会不再接收事件,既然收不到事件,那么也就不会再去更新UI了,因此可以在Activity中将这个Disposable保存起来,当Activity退出时,切断它即可.
- 如果有多个Disposable,RxJava中已经内置了一个容器CompositeDisposable,每当我们得到一个Disposable时就调用CompositeDisposable.add()将它添加到容器中,在退出的时候,调用CompositeDisposable.clear()即可切断所有的接收事件.
- 网络或者数据库操作时候就在Observable中操作,订阅的时候设置发送数据的线程为子线程
- 如果发送的数据类型不是我们要接收的类型,比如发送的是int类型,我们想要String类型的,就可以通过map,map是RxJava中最简单的一个变换操作符了, 它的作用就是对上游发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化.
! [](http://i.imgur.com/hcB5ilf.png)
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "Rxjava" + integer; //这就是要发送的数据,int
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Toast.makeText(MainActivity.this, "看这里" + s, Toast.LENGTH_LONG).show(); //String
}
});
- FlatMap flatMap是一个非常强大的操作符,FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
! [](http://i.imgur.com/g3bHNLv.png)
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
}
}).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("我 是 =" + integer);
}
return Observable.fromIterable(list).delay(10 , TimeUnit.SECONDS);//延时
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e("qiukailong", s);
}
});
- 打印结果
! [](http://i.imgur.com/IfJSrss.png)
- 使用flatmap,flatMap并不保证事件的顺序,如果需要保证顺序则需要使用concatMap.把上面的flatmap换成concatMap就可以了,打印结果
! [](http://i.imgur.com/dTcFSjx.png)
- zip操作符,Zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
! [](http://i.imgur.com/Yt0naZ3.png)
- 创建两个Observable,在不同的线程中发送事件
final Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.e("qiukailong", "1");
emitter.onNext(2);
Log.e("qiukailong", "2");
emitter.onNext(3);
Log.e("qiukailong", "3");
emitter.onNext(4);
Log.e("qiukailong", "4");
}
}).subscribeOn(Schedulers.io()); //在子线程中
final Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("A");
Log.e("qiukailong", "A");
emitter.onNext("B");
Log.e("qiukailong", "B");
emitter.onNext("C");
Log.e("qiukailong", "C");
emitter.onComplete();
emitter.onNext("D");
Log.e("qiukailong", "D");
}
}).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.e("qiukailong", "onSubscribe");
}
@Override
public void onNext(String value) {
Log.e("qiukailong", value);
}
@Override
public void onError(Throwable e) {
Log.e("qiukailong", "onError");
}
@Override
public void onComplete() {
Log.e("qiukailong", "onComplete");
}
});
- 打印结果
! [](http://i.imgur.com/nf0QX0Q.png)
- 使用zip时,Observable1和Observable2发送数据,如果Observable1发送快,而Observable2发送慢,Observable1的事件会存储到某个地方,但是如果事件过多就会导致omm,因为存储的数据太多,其他情况发送和接收事异步的话也会出现oom
- 还有filter操作符,过滤掉自己不想要的
- sample操作符,设定每隔指定时间从发送事件那里取出事件
- Flowable和Subscriber
final Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
//flowable中有大小为128的储存器,如果subscribe没有 s.request(Long.MAX_VALUE)写这个,就会把要发送的事件储存起
//来,如果通过外部调用的 s.request(Long.MAX_VALUE)时候指定数量,依然可以取出事件
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.e("qiukailong","1");
emitter.onNext(2);
Log.e("qiukailong", "2");
emitter.onNext(3);
Log.e("qiukailong", "3");
}
}, BackpressureStrategy.ERROR); //BackpressureStrategy.BUFFER没有大小限制超过128也没事
//BackpressureStrategy.DROP 把存不下的事件丢弃
//BackpressureStrategy.LATEST只保留最新的事件
Subscriber<Integer> subscriber = new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.e("qiukailong", "onSubscribe");
//如果不想接收事件就调用s.cancel();
s.request(Long.MAX_VALUE); //代表能处理多少事件,如果发送事件大于这个处理数量,就会抛出
// onErrorio.reactivex.exceptions.MissingBackpressureException: create: could not emit value due to lack of requests
}
@Override
public void onNext(Integer integer) {
Log.e("qiukailong", integer + "");
}
@Override
public void onError(Throwable t) {
Log.e("qiukailong", "onError" + t);
}
@Override
public void onComplete() {
Log.e("qiukailong", "onComplete");
}
};
flowable.subscribe(subscriber);
//当接收和发送在同意线程中,可以通过emitter.requested()获取接收事件的数量