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<String>() {//感覺不是必須的,如果不用處理註冊結果,就不需要了吧
         @Override
         public void accept(String s) throws Exception {
             //先對註冊的結果進行一些處理,這步不是必須的
         }
     })
     .observeOn(Schedulers.io())//在io線程處理登錄請求
     .flatMap(new Function<String, ObservableSource<String>>() {
         @Override
         public ObservableSource<String> apply(String s) throws Exception {
             //發起登錄的網絡請求
             return api.login("ckw");
         }
     })
     .observeOn(AndroidSchedulers.mainThread())//在主線程處理登錄請求結果
     .subscribe(new Consumer<String>() {
         @Override
         public void accept(String s) throws Exception {
             Log.d("----", "accept: 登錄成功");
         }
     }, new Consumer<Throwable>() {
         @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();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章