RxJava2深度学习(二)

上一篇学完了Observable和Observer,这一篇学一下map操作符和flatMap操作符

1.先看一下map操作符:
map是RxJava中最简单的一个变换操作符了,map操作符的作用是将上游(Observable)发送的每一个事件,转换成一个函数,使得每一个上游发送的事件都按照指定的规则去做。

下面先看一个例子:

  Observable.create(new ObservableOnSubscribe<Integer>() {
      @Override
      public void subscribe(ObservableEmitter<Integer> e) throws Exception {
          Log.d("----", "subscribe: 发送的信息:"+1);
          e.onNext(1);
          Log.d("----", "subscribe: 发送的信息:"+2);
          e.onNext(2);
          Log.d("----", "subscribe: 发送的信息:"+3);
          e.onNext(3);
          Log.d("----", "subscribe: 完成");
          e.onComplete();
      }
  }).map(new Function<Integer, String>() {
      @Override
      public String apply(Integer integer) throws Exception {
          //map的作用就是转化,这里将int类型的数据 转换为 String类型的数据
          return "this is " + integer;
      }
  }).subscribe(new Consumer<String>() {

      @Override
      public void accept(String s) throws Exception {
          Log.d("----", "accept: 接收到的信息:"+s);
      }
  });

在上游我们发送的是数字类型, 而在下游我们接收的是String类型, 中间起转换作用的就是map操作符

看一下Log输出:

02-05 16:19:06.549 14418-14418/com.ckw.rxjava2demo D/----: subscribe: 发送的信息:1
02-05 16:19:06.549 14418-14418/com.ckw.rxjava2demo D/----: accept: 接收到的信息:this is 1
02-05 16:19:06.549 14418-14418/com.ckw.rxjava2demo D/----: subscribe: 发送的信息:2
02-05 16:19:06.549 14418-14418/com.ckw.rxjava2demo D/----: accept: 接收到的信息:this is 2
02-05 16:19:06.550 14418-14418/com.ckw.rxjava2demo D/----: subscribe: 发送的信息:3
02-05 16:19:06.550 14418-14418/com.ckw.rxjava2demo D/----: accept: 接收到的信息:this is 3
02-05 16:19:06.550 14418-14418/com.ckw.rxjava2demo D/----: subscribe: 完成

从log信息中我们可以看到,上游发送的是Int类型的数据,通过map操作符,转成了String。

接着看flatMap:
FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
上游每发送一个事件, flatMap都将创建一个新的水管, 然后发送转换之后的新的事件,
下游接收到的就是这些新的水管发送的数据. 这里需要注意的是, flatMap并不保证事件的顺序

看一下例子:

 Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                Log.d("----", "subscribe: 上游发送:1");
                e.onNext(1);
                Log.d("----", "subscribe: 上游发送:2");
                e.onNext(2);
                Log.d("----", "subscribe: 上游发送:3");
                e.onNext(3);
                Log.d("----", "subscribe: 上游发送完毕");
                e.onComplete();
            }
        }).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("this is "+integer);
                }
                return Observable.fromIterable(list).delay(10,TimeUnit.MILLISECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d("----", "accept: 接收到的信息:"+s);
            }
        });

Observable.fromIterable:
此方法接收一个继承自Iterable接口的参数,简单的说就是java中的集合类。因此你可以传入一个list集合等等

看一下Log输出:

02-05 16:23:29.263 15724-15724/com.ckw.rxjava2demo D/----: subscribe: 上游发送:1
02-05 16:23:29.281 15724-15724/com.ckw.rxjava2demo D/----: subscribe: 上游发送:2
02-05 16:23:29.282 15724-15724/com.ckw.rxjava2demo D/----: subscribe: 上游发送:3
02-05 16:23:29.283 15724-15724/com.ckw.rxjava2demo D/----: subscribe: 上游发送完毕
02-05 16:23:29.291 15724-15772/com.ckw.rxjava2demo D/----: accept: 接收到的信息:this is 1
02-05 16:23:29.292 15724-15773/com.ckw.rxjava2demo D/----: accept: 接收到的信息:this is 2
02-05 16:23:29.292 15724-15774/com.ckw.rxjava2demo D/----: accept: 接收到的信息:this is 3

3.模拟注册登录:
使用FlatMap模拟用户先注册,注册成功后直接登录的功能:

final Api api = create().create(Api.class);
//        //之前有说过,只能subscribeOn一次,可以observeOn多次
api.register("ckw")//发起注册请求
     .subscribeOn(Schedulers.io())//在io线程发起网络请求
     .observeOn(AndroidSchedulers.mainThread())//在主线程处理注册请求结果
     .doOnNext(new Consumer() {//感觉不是必须的,如果不用处理注册结果,就不需要了吧
         @Override
         public void accept(String s) throws Exception {
             //先对注册的结果进行一些处理,这步不是必须的
         }
     })
     .observeOn(Schedulers.io())//在io线程处理登录请求
     .flatMap(new Function>() {
         @Override
         public ObservableSource apply(String s) throws Exception {
             //发起登录的网络请求
             return api.login("ckw");
         }
     })
     .observeOn(AndroidSchedulers.mainThread())//在主线程处理登录请求结果
     .subscribe(new Consumer() {
         @Override
         public void accept(String s) throws Exception {
             Log.d("----", "accept: 登录成功");
         }
     }, new Consumer() {
         @Override
         public void accept(Throwable throwable) throws Exception {
             Log.d("----", "accept: 登录失败");
         }
     });

在这里我的返回值都是String,只是一个模拟的效果,实际上还是要根据自己的需求,创建数据类。

这是模拟的返回Retrofit的方法

private static Retrofit create() {
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        builder.readTimeout(10, TimeUnit.SECONDS);
        builder.connectTimeout(9, TimeUnit.SECONDS);

        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(interceptor);
        }

        return new Retrofit.Builder().baseUrl( "http://10.71.33.67:80")
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

你可能感兴趣的:(Android)