RxJava接触挺久了,但是在实际项目中大部分都是配合retrofit使网络请求使用,其他需求比较少,就是想用的时候会忘记怎么使用,所以这里做个笔记,希望也能帮到他人
本文基于RxJava2.0
自己觉得知道下面几点就比较清楚了
创建被观察者:使用基本的创建方式create()
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
//通知观察者
e.onNext("通知观察者");
e.onComplete();
}
});
创建观察者
Observer observer = new Observer() {
//RxJava 2.0 中新增的,传递参数为Disposable ,Disposable 相当于RxJava1.x中的Subscription,用于解除订阅。
@Override
public void onSubscribe(Disposable d) {
//可用于取消订阅
d.dispose();
//还可以判断是否处于取消状态
//boolean b=d.isDisposed();
}
//观察者接收到通知,进行相关操作
@Override
public void onNext(String o) {
Log.d("","接收到观察者发出的数据");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
订阅,将被观察者和观察者关联上
observable.subscribe(observer);
just(T…): 将传入的参数依次发送出去
Observable observable = Observable.just("Hello", "Hi", "Aloha");
// 将会依次调用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
Observable.from… 拆分成具体对象后,依次发送出去
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
// 将会依次调用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
看下面的code 想大家看下注释就会明白了
Observable.just("a", "b", "c", "d")
.subscribeOn(Schedulers.io())//指定数据发射在哪个线程执行
.observeOn(Schedulers.newThread())//observeOn方法决定他下面的方法执行在哪个线程中
.map(func1)//一个新线程中执行
.observeOn(Schedulers.io())//observeOn方法决定他下面的方法执行在哪个线程中
.map(func2)//io线程执行
.observeOn(AndroidSchedulers.mainThread())////observeOn方法决定他下面的方法执行在哪个线程中
.subscribe(consumer);//ui线程执行
Function<String, String> func1 = new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
return s + "===newThread===";
}
};
Function<String, String> func2 = new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
return s + "===io===";
}
};
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String o) throws Exception {
Log.d("call", o.toString());
}
};
场景五: 定时操作
示例中会伴有Rxjava 的操作符出现,使用时会进行说明
由于在Android UI线程中不能做一些耗时操作,比如网络请求,大文件保存等,所以在开发中经常会碰到异步处理的情况,我们最典型的使用场景是RxJava+Retrofit处理网络请求
@GET("/user")
public Observable getUser(@Query("userId") String userId);
getUser(userId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onNext(User user) {
userView.setUser(user);//使用得到的结果数据
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
假如在得到User数据后,需要跟新本地的用户数据,也是将新的额数据显示到View上,两步操作都是同时的,这个时候我们可以借助”doOnNext “操作符
doOnNext() 方法 是当onNext发生时才会被调用
doOnNext()允许我们在每次输出一个元素之前做一些额外的事情
注意:
在doOnNext()中不要去改变数据的值
processUser(user); // 尝试修正 User 数据
userView.setUser(user);//显示数据
代码
getUser(userId)
.doOnNext(new Consumer() {
@Override
public void accept(User user) throws Exception {
processUser(user);//更改数据
}
})
.observeOn(AndroidSchedulers.mainThread())//ui线程
.subscribe(new Observer() {
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(User user) {
userView.setUser(user);//展示数据
}
});
如果请求getUser()之前需要getToken接口返回的数据才能访问
使用”flatmap”操作符
作用:将一个类型依据程序逻辑转换成另一种类型
@GET("/token")
public Observable getToken();
@GET("/user")
public Observable getUser(@Query("token") String token, @Query("userId") String userId);
getToken()
.flatMap(new Function>() {
@Override
public Observable> apply(String token) throws Exception {
return getUser(token, userId);//第二次网络请求
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(User user) {
//获取到的用户数据
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
使用”fromIterable”操作符 ,作用:遍历发送列表的每个Item
ArrayList<String> arr1 = new ArrayList<>();
arr1.add("url1");
arr1.add("url2");
arr1.add("url3");
Observable.just(arr1)
.subscribeOn(Schedulers.newThread())//指定数据发射在哪个线程执行
.flatMap(new Function<List<String>, Observable<String>>() {
@Override
public Observable<String> apply(List<String> strings) throws Exception {
Log.d("flatMap Thread ::: ", Thread.currentThread().getName());
return Observable.fromIterable(strings);//遍历列表发送
}
})
.observeOn(AndroidSchedulers.mainThread())//切换到主线程
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("subscribe Thread ::: ", Thread.currentThread().getName());
Log.d("subscribe === ", s);
}
});
有时需要请求多个接口和,将多个接口请求回来的数据合并后使用,可以使用”zip”操作符
作用:组合多个Observable发射的数据集合,然后再发射这个组合结果Observable
Observable.zip(getData1(), getData2(), new BiFunction<List<String>, List<String>, String>() {
@Override
public String apply(List<String> strings, List<String> strings2) throws Exception {
return strings.get(0) + strings.get(0);//发送组合后的新数据
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("接受新数据:::", s);
}
});
/**
* 模拟请求数据1
*
* @return
*/
private Observable> getData1() {
return Observable.create(new ObservableOnSubscribe>() {
@Override
public void subscribe(ObservableEmitter> e) throws Exception {
ArrayList contacters = new ArrayList<>();
contacters.add("location:张三");
contacters.add("location:李四");
contacters.add("location:王五");
e.onNext(contacters);
e.onComplete();
}
});
}
/**
* 模拟获取数据2
*
* @return
*/
private Observable> getData2() {
return Observable.create(new ObservableOnSubscribe>() {
@Override
public void subscribe(ObservableEmitter> e) throws Exception {
ArrayList contacters = new ArrayList<>();
contacters.add("net:Zeus");
contacters.add("net:Athena");
contacters.add("net:Prometheus");
e.onNext(contacters);
e.onComplete();
}
});
}
使用timer做定时操作。当有“x秒后执行y操作”类似的需求的时候,想到使用timer
* 例如:2秒后输出日志“hello world”,然后结束。
//2秒后执行
Observable.timer(2, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())//切换到主线程
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
tv_msg.setText("hello --- world");
}
});
更多操作符使用,后续有时间再记录