变换操作符号
需求是:当我们的操作是当注册成功后去登录的连贯过程
Map操作符
Map操作是用来转换结果的方式
Observable.create(new ObservableOnSubscribe<Integer>(){
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d(TAG,"emitt:" + Thread.currentThread().getName());
e.onNext(1);
}
}).subscribeOn(Schedulers.io())
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
Log.d(TAG,"map:"+Thread.currentThread().getName());
return "This is "+ integer;
}
})
.observeOn(Schedulers.newThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG,"consumer:"+Thread.currentThread().getName());
}
});
//运行结果
03-15 15:29:44.750 6275-6343/com.example.uds.recyclerviewtest D/MAP: emitt:RxCachedThreadScheduler-1
03-15 15:29:44.750 6275-6343/com.example.uds.recyclerviewtest D/MAP: map:RxCachedThreadScheduler-1
03-15 15:29:44.752 6275-6344/com.example.uds.recyclerviewtest D/MAP: consumer:RxNewThreadScheduler-1
注意顺序
Observable.create(new ObservableOnSubscribe<Integer>(){
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d(TAG,"emitt:" + Thread.currentThread().getName());
e.onNext(1);
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
Log.d(TAG,"map:"+Thread.currentThread().getName());
return "This is "+ integer;
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG,"consumer:"+Thread.currentThread().getName());
}
});
//运行结果
03-15 15:31:36.752 7944-8043/com.example.uds.recyclerviewtest D/MAP: emitt:RxCachedThreadScheduler-1
03-15 15:31:36.758 7944-8044/com.example.uds.recyclerviewtest D/MAP: map:RxNewThreadScheduler-1
03-15 15:31:36.758 7944-8044/com.example.uds.recyclerviewtest D/MAP: consumer:RxNewThreadScheduler-1
调换了map的所处的位置
当map在subscribeOn的后面,map执行是在和上游线程一个线程中
当map在observeOn的后面,map执行是在和下有线程一个线程中
上述中的 Map 我们是将Integer 转换为了 String 类型的结果
FlatMap
FlatMap 将一个发送事件的上游 Observable 变换为多个发送事件的 Observables,然后将他们发射的事件合并后放进一个单独的Observable中
FlatMap 不保证事件的顺序
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<String>();
for(int i=0;i<3;i++){
list.add("I am value "+integer);
}
return Observable.fromIterable(list).delay(100, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG,s);
}
});
//运行结果
03-19 13:25:47.040 4531-4597/com.example.uds.recyclerviewtest D/MAP: I am value 1
03-19 13:25:47.040 4531-4597/com.example.uds.recyclerviewtest D/MAP: I am value 1
03-19 13:25:47.041 4531-4598/com.example.uds.recyclerviewtest D/MAP: I am value 2
03-19 13:25:47.041 4531-4598/com.example.uds.recyclerviewtest D/MAP: I am value 2
03-19 13:25:47.041 4531-4598/com.example.uds.recyclerviewtest D/MAP: I am value 2
03-19 13:25:47.042 4531-4597/com.example.uds.recyclerviewtest D/MAP: I am value 1
03-19 13:25:47.043 4531-4597/com.example.uds.recyclerviewtest D/MAP: I am value 3
03-19 13:25:47.043 4531-4597/com.example.uds.recyclerviewtest D/MAP: I am value 3
03-19 13:25:47.043 4531-4597/com.example.uds.recyclerviewtest D/MAP: I am value 3
Observable.fromIterable(list) 会将list中的每一个item都经过onNext发送出去
concatMap
concatMap 的效果和 flatMap的效果几乎是一样的,不过 concatMap 是严格按照顺序执行的
注册后登陆的代码示例
public interface API {
@POST("product/detail.do")
@FormUrlEncoded
Observable<Product> getDetails(@Field("productId") Integer productId);
@POST("user/login.do")
@FormUrlEncoded
Observable<ResponseBody> login(@Field("username") String username,@Field("password") String password);
@POST("product/upload.do")
@Multipart
Observable<ResponseBody> uploadFile(@Part MultipartBody.Part upload_file);
}
final HttpUrl loginUrl = HttpUrl.parse("http://192.168.125.120:8080/manage/user/login.do");
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
private final HashMap<HttpUrl,List<Cookie>> cookieStore = new HashMap<HttpUrl, List<Cookie>>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url,cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookieList = cookieStore.get(loginUrl);
return cookieList != null ? cookieList : new ArrayList<Cookie>();
}
}).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.125.120:8080/manage/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
final API api = retrofit.create(API.class);
api.login("admin","admin")
.subscribeOn(Schedulers.io())//io线程中处理请求
.observeOn(AndroidSchedulers.mainThread())//主线程中处理结果
.doOnNext(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws Exception {
//可以在主线程根据相应结果做一些处理
//比如登陆成功 或者失败怎么处理
}
})
.observeOn(Schedulers.io())//切换到io线程中发起查询数据的网络请求
.flatMap(new Function<ResponseBody, ObservableSource<Product>>() {
@Override
public ObservableSource<Product> apply(ResponseBody responseBody) throws Exception {
return api.getDetails(26);
}
}).observeOn(AndroidSchedulers.mainThread())//回到主线程中处理结果
.subscribe(new Consumer<Product>() {
@Override
public void accept(Product product) throws Exception {
Log.d(TAG,product.toString());
}
});