前言
人生匆匆忙忙就几十年骚年们趁着自己年轻做自己想做的事吧
本人只是简单的技术记载,写得不好不要喷
RxJava:是一个基于观察者模式的异步的框架,具体网上一百度一大堆自己看吧。
RxJava的使用
在Android项目中使用RxJava首先要添加依赖
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
1 创建被观察者
/**
* @创建被观察者
* @method: 当被观察者被订阅的时候回调的方法
*/
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
/**
*
* @param e 被观察者发送数据的对象
* @throws Exception 可能发生的异常
*/
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("小黑");
e.onNext("小黑黑");
}
});
这就是一个简单的被观察者的创建使用的是create()操作符内部传入一个监听订阅关系的接口。
2 观察者的创建
/**
* @创建观察者
* @method 处理被观察者发射的数据
*/
Observer<String> observer = new Observer<String>() {
/**
* 处理数据之前的准备操作的方法
* @param d 一个用来切断订阅关系的对象
*/
@Override
public void onSubscribe(Disposable d) {
}
/**
* 处理OnNext()发射的数据
* @param value
*/
@Override
public void onNext(String value) {
Log.d(TAG, "onNext: " + value);
}
/***
* 处理发射出错的逻辑
* @param e 保存了错误信息的对象
*/
@Override
public void onError(Throwable e) {
}
/***
* 处理发射出完成的逻辑
*/
@Override
public void onComplete() {
}
};
观察者是用来处理被观察者发射器发射的数据的对象。
3 建立订阅关系
// 观察者订阅被观察者
observable.subscribe(observer);
通过这一段代码来建立观察者和被观察者的订阅的关系。
总结:RxJava就是被观察者发送数据的操作触发观察者内部的方法对被观察者的操作的处理。
RxJava中的线程的处理
在Android的开发过程中我们的后台的各种耗时的操作不可能在主线程中进行,因此这就要我们学会对线程的切换。
// 用来指定subscribe()发生的线程
.subscribeOn(Schedulers.newThread())
// 指定下游的回调发生的线程
.observeOn(AndroidSchedulers.mainThread())
RxJava 中,已经内置了很多线程选项供我们选择,例如有:
Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作;
Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作;
Schedulers.newThread() 代表一个常规的新线程;
AndroidSchedulers.mainThread() 代表Android的主线程
RxJava 内置的线程调度器的确可以让我们的线程切换得心应手,但其中也有些需要注意的地方。
简单地说,subscribeOn() 指定的就是发射事件的线程,observerOn 指定的就是订阅者接收事件的线程。
多次指定发射事件的线程只有第一次指定的有效,也就是说多次调用 subscribeOn() 只有第一次的有效,其余的会被忽略。
但多次指定订阅者接收线程是可以的,也就是说每调用一次 observerOn(),下游的线程就会切换一次。
操作符
map() 操作符是对单一的对象的转化,意思就是我可以通过map()将被观察者发送的int数据转化为String类型的数据。
.map(new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
return "被转化的字符串为"+s;
}
})
这段代码就是对map()操作符的使用他的作用就是把发射的数据进行处理,处理完的数据交给观察者中的指定的方法进行处理。
concat() 他的作用就是做到不交错的发送两个或者多个被观察者的事件,并且只有前一个调用了onComplete()之后下一个才会被订阅。
/**
* @创建被观察者
* @method: 当被观察者被订阅的时候回调的方法
*/
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
/**
*
* @param e 被观察者发送数据的对象
* @throws Exception 可能发生的异常
*/
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("小黑");
e.onNext("小黑黑");
// e.onComplete();
}
});
Observable<String> observable1 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("111111");
e.onNext("222222");
}
});
/**
* @创建观察者
* @method 处理被观察者发射的数据
*/
Observer<String> observer = new Observer<String>() {
/**
* 处理数据之前的准备操作的方法
* @param d 一个用来切断订阅关系的对象
*/
@Override
public void onSubscribe(Disposable d) {
}
/**
* 处理OnNext()发射的数据
* @param value
*/
@Override
public void onNext(String value) {
Log.d(TAG, "onNext: " + value);
}
/***
* 处理发射出错的逻辑
* @param e 保存了错误信息的对象
*/
@Override
public void onError(Throwable e) {
}
/***
* 处理发射出完成的逻辑
*/
@Override
public void onComplete() {
}
};
// 观察者订阅被观察者
observable
.concat(observable,observable1)
// 用来指定subscribe()发生的线程
.subscribeOn(Schedulers.newThread())
// 指定下游的回调发生的线程
.observeOn(AndroidSchedulers.mainThread())
// .map(new Function<String, String>() {
// @Override
// public String apply(String s) throws Exception {
// return "被转化的字符串为"+s;
// }
// })
.subscribe(observer);
}
以上代码通过concat()实现了在观察者中同时处理他订阅的两个被观察者的事件。
zip操作符就会对两个发射器发送的数据的结合,结合最后的组合以发射的少的组合的个数为准。
Observable<String> observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext("你好");
}
});
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(2);
e.onNext(3);
}
});
Observable.zip(observable1, observable, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return s+integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: "+s);
}
});
flatmap操作符的使用,将一个被观察者转化为多个被观察者发送给观察者操作
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
});
observable1.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<4;i++){
list.add("this value is "+i);
}
return Observable.fromIterable(list);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: "+s);
}
});
concatmap和flatmap的区别就是二者是不是有顺序
distinct()操作符是对发送的数据进行去重的使用很简单
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
});
observable1.distinct()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: "+integer);
}
});
Fliter是一个过滤器是对发送的数据进行筛选
Observable<Integer> observable1 = Observable.just(1, 20, 65, -5, 7, 19)
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Exception {
return integer>2;
}
});
observable1.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: "+integer);
}
});
buffer操作符:
buffer(count ,skip)
count :每段数据的数据量
skip:将接收的数据分为几段
doNext():它的作用是让订阅者在接收到数据之前干点有意思的事情。假如我们在获取到数据之前想先保存一下它
Observable.just(1, 2, 3, 4)
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("doOnNext 保存 " + integer + "成功" + "\n");
Log.e(TAG, "doOnNext 保存 " + integer + "成功" + "\n");
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("doOnNext :" + integer + "\n");
Log.e(TAG, "doOnNext :" + integer + "\n");
}
});
skip 操作符:接受一个 long 型参数 count ,代表跳过 count 个数目开始接收。
take 操作符:接受一个 long 型参数 count ,代表至多接收 count 个数据
just操作符:就是一个简单的发射器依次调用 onNext() 方法。
SIngle: 只会接收一个参数,而 SingleObserver 只会调用 onError() 或者 onSuccess()
Single.just(2)
.subscribe(new SingleObserver<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Toast.makeText(NewActivity.this, "结束订阅的关系", Toast.LENGTH_SHORT).show();
}
@Override
public void onSuccess(Integer value) {
Toast.makeText(NewActivity.this, "操作成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(NewActivity.this, "操作失败", Toast.LENGTH_SHORT).show();
}
});
debounce:去除发送频率过快的项。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("小黑"); // skip
Thread.sleep(400);
emitter.onNext("小黑黑"); // deliver
Thread.sleep(505);
emitter.onNext("小黑黑黑"); // skip
Thread.sleep(100);
emitter.onNext("小黑黑嘿嘿"); // deliver
Thread.sleep(605);
emitter.onNext("是的是小黑"); // deliver
Thread.sleep(510);
emitter.onComplete();
}
}).debounce(300, TimeUnit.MILLISECONDS)
.subscribe(
new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Toast.makeText(NewActivity.this, ""+s, Toast.LENGTH_SHORT).show();
Log.d(TAG, "accept: "+s);
}
}
);
}
defer :就是每次订阅都会创建一个新的Observable
last :操作符仅取出可观察到的最后一个值,或者是满足某些条件的最后一项。
merge:merge 顾名思义,熟悉版本控制工具的你一定不会不知道 merge 命令,而在 Rx 操作符中,merge 的作用是把多个 Observable 结合起来,接受可变参数,也支持迭代器集合。注意它和 concat 的区别在于,不用等到 发射器 A 发送完所有的事件再进行发射器 B 的发送。
reduce:操作符每次用一个方法处理一个值,可以有一个 seed 作为初始值
Observable.just(1,2,3)
.reduce(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
return integer2-integer;
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: "+integer);
}
});
}
scan:作用是和reduce一样的只不过reduce只输出结果,scan会输出过程