吐槽
昨天学啊学,感觉头都炸了,这块感觉真的是很难受,但是自己的当前的目标是学会Rxjava+Retrofit结合在一起的网络框架套路,然后用到项目里面。自己的卡片项目也要加油,今天去和后台交流下。
Rxjava里面的线程问题
普通没有设置的时候,上游和下游(观察者和被观察者)在一个线程里面
但是
这样的话好多操作就完成不了,这样就很尴尬了
所以可以指定上游和下游的线程
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d("233", "Observable thread is : " + Thread.currentThread().getName());
Log.d("233", "emit 1");
e.onNext(1);
}
});
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("233", "Observer thread is :" + Thread.currentThread().getName());
Log.d("233", "onNext: " + integer);
}
};
observable.subscribeOn(Schedulers.newThread())//上游指定的发送事件的线程
.observeOn(AndroidSchedulers.mainThread())//下游指定的接收的线程
.subscribe(consumer);
}
注意
- subscribeOn() 指定的是上游发送事件的线程, observeOn() 指定的是下游接收事件的线程.
- 多次指定上游的线程只有第一次指定的有效, 也就是说多次调用subscribeOn() 只有第一次的有效, 其余的会被忽略
- 多次指定下游的线程是可以的, 也就是说每调用一次observeOn() , 下游的线程就会切换一次
在RxJava中, 已经内置了很多线程选项供我们选择
chedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
Schedulers.newThread() 代表一个常规的新线程
AndroidSchedulers.mainThread() 代表Android的主线程
Rxjava2.0的操作符
这块东西很多唉。自己就简单看大佬的博客,学了几种常用的,其他的以后有用再说
Map操作符
map是RxJava中最简单的一个变换操作符了, 它的作用就是对上游发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化.
就是把上游的东西转化成自己规定的东西
看代码例子
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 "This is result" + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("233",s);
}
});
结果
上游本来是发了3个int的事件,然后用Map转换为string类型,发给下游
就是个中转站
FlatMap操作符
FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
这样说起来很绕口,就是把上游的发的一个事件,可以改变这个事件的数量和格式
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 {
final List<String> list = new ArrayList<>();
for (int i = 0;i < 3;i++){
list.add("value "+integer);
}
return Observable.fromIterable(list).delay(50, TimeUnit.MICROSECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("233",s);
}
});
结果:
就是把发送的数据3个int类型的
每一个都变成3个String类型的
然后给下游接收到
//但是发送的时候顺序可能不一样
concatMap操作符
flatMap的作用几乎一模一样, 只是它的结果是严格按照上游发送的顺序来发送的
Zip操作符
通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
就是把两个上游的数据整合在一起,然后发给下游。
但是直接这样操作就很有问题
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d("233","emit 1");
e.onNext(1);
Log.d("233","emit 2");
e.onNext(2);
Log.d("233","emit 3");
e.onNext(3);
Log.d("233","emit 4");
e.onNext(4);
Log.d("233","emit complete1");
e.onComplete();
}
});
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
Log.d("233","emit A");
e.onNext("A");
Log.d("233","emit B");
e.onNext("B");
Log.d("233","emit C");
e.onNext("C");
Log.d("233","emit complete2");
e.onComplete();
}
});
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.d("233","onSubscribe");
}
@Override
public void onNext(String value) {
Log.d("233","onNext"+value);
}
@Override
public void onError(Throwable e) {
Log.d("233","OnErron");
}
@Override
public void onComplete() {
Log.d("233","oncomplete");
}
});
结果:
发现这个有问题
水管一发,水管2后发
所以为了解决这个问题
我们就开两个线程就好了
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d("233","emit 1");
e.onNext(1);
Thread.sleep(1000);
Log.d("233","emit 2");
e.onNext(2);
Thread.sleep(1000);
Log.d("233","emit 3");
e.onNext(3);
Thread.sleep(1000);
Log.d("233","emit 4");
e.onNext(4);
Thread.sleep(1000);
Log.d("233","emit complete1");
e.onComplete();
}
}).subscribeOn(Schedulers.io());
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
Log.d("233","emit A");
e.onNext("A");
Thread.sleep(1000);
Log.d("233","emit B");
e.onNext("B");
Thread.sleep(1000);
Log.d("233","emit C");
e.onNext("C");
Thread.sleep(1000);
Log.d("233","emit complete2");
e.onComplete();
}
}).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.d("233","onSubscribe");
}
@Override
public void onNext(String value) {
Log.d("233","onNext"+value);
}
@Override
public void onError(Throwable e) {
Log.d("233","OnErron");
}
@Override
public void onComplete() {
Log.d("233","oncomplete");
}
});
结果:
注意:
这块其实还有很多问题,下一篇博客再说
总结
就觉得Rxjava的操作符很厉害唉,继续学习了唉
参考的大佬博客