RxJava學(xué)習(xí)刁绒,封裝一個(gè)簡(jiǎn)單的map 和flatMap

RxJava 筆記

注意:這只是學(xué)習(xí)的過程,為了學(xué)習(xí)rxjava是怎么由callback嵌套轉(zhuǎn)換而來霞幅,其中的map和flatMap 都只是精簡(jiǎn)過后的一個(gè)概念,不是真正的樣子

感謝

W_BinaryTree
2樓 · 2017.05.12 01:07
flatMap不僅僅是把item封裝成observable量瓜。 還有個(gè)merge的過程司恳。

同步時(shí)

Response newsList = netApi.getNewsList(0,10);
String title = findLatestTitle(newsList);
Uri uri = netApi.save(title);

異步時(shí)嵌套

1. 三個(gè)不同的接口

public class MainActivity extends AppCompatActivity {
    String url = "http://op.juhe.cn/yi18/news/newsclass";

    interface ApiCallback {
        void onSuccess(String data);

        void onError(Throwable e);
    }


    interface TransferCallback {
        void onSuccess(Data data);

        void onError(Throwable e);
    }

    interface ResultCallback {
        void onSuccess(Uri uri);

        void onError(Throwable e);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("ss", "sss");
        findViewById(R.id.btn).setOnClickListener(v -> {
            request(new ApiCallback() {
                @Override
                public void onSuccess(String data) {
                            Data dat = tansfer(data);
                            save(data, new ResultCallback() {
                                @Override
                                public void onSuccess(Uri uri) {
                                }

                                @Override
                                public void onError(Throwable e) {
                                }
                            });
                    });
                }
                @Override
                public void onError(Throwable e) {
                }
            });
        });
    }

    /**
     * 1. 請(qǐng)求網(wǎng)絡(luò)獲取數(shù)據(jù)
     *
     * @param apiCallback
     */
    public void request(ApiCallback apiCallback) {
        OkGo.get(url)
                .params("key", "2e6f34e3fe8fa96e5384021477f8e224")
                .execute(new StringCallback() {

                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        Log.d("MainActivity", "onSuccess: " + s);
                        apiCallback.onSuccess(s);
                    }

                    @Override
                    public void onError(Call call, Response response, Exception e) {
                        apiCallback.onError(e);
                    }
                });
    }

    /**
     * 2. 將獲取的數(shù)據(jù)轉(zhuǎn)換成對(duì)象
     */
    public Data tansfer(String s) {
            Data data = GsonUtils.GsonToBean(s, Data.class);
            return data;
    }

    /**
     * 3.將對(duì)象中的某個(gè)數(shù)據(jù)保存
     */
    public void save(Data data, ResultCallback resultCallback) {
        try {
            ResultBean result = data.getResult();
            ListBean list = result.getList();
            List<TngouBean> tngou = list.getTngou();

            String s = GsonUtils.GsonString(list);
            SharedPreferences config = getSharedPreferences("config", MODE_PRIVATE);
            config.edit().putString("tag", s).apply();

            resultCallback.onSuccess(Uri.parse(s));
        } catch (Throwable e) {
            resultCallback.onError(e);
        }
    }
}

2. 將三個(gè)接口改為同一個(gè)接口,用泛型來確定onSuccess()的內(nèi)容

public class MainActivity extends AppCompatActivity {
    String url = "http://op.juhe.cn/yi18/news/newsclass";

    interface Callback<T> {
        void onSuccess(T data);

        void onError(Throwable e);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("ss", "sss");
        findViewById(R.id.btn).setOnClickListener(v -> {
            request(new Callback<String>() {
                @Override
                public void onSuccess(String data) {
                    tansfer(data, new Callback<Data>() {
                        @Override
                        public void onSuccess(Data data) {
                            save(data, new Callback<Uri>() {
                                @Override
                                public void onSuccess(Uri uri) {
                                }

                                @Override
                                public void onError(Throwable e) {
                                }
                            });
                        }
                        @Override
                        public void onError(Throwable e) {
                        }
                    });
                }
                @Override
                public void onError(Throwable e) {
                }
            });

        });
    }

    /**
     * 1. 請(qǐng)求網(wǎng)絡(luò)獲取數(shù)據(jù)
     *
     * @param apiCallback
     */
    public void request(Callback apiCallback) {
        OkGo.get(url)
                .params("key", "2e6f34e3fe8fa96e5384021477f8e224")
                .execute(new StringCallback() {

                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        Log.d("MainActivity", "onSuccess: " + s);
                        apiCallback.onSuccess(s);
                    }

                    @Override
                    public void onError(Call call, Response response, Exception e) {
                        apiCallback.onError(e);
                    }
                });
    }

    /**
     * 2. 將獲取的數(shù)據(jù)轉(zhuǎn)換成對(duì)象
     *
     * @param transferCallback
     */
    public void tansfer(String s, Callback transferCallback) {
        try {
            Data data = GsonUtils.GsonToBean(s, Data.class);
            transferCallback.onSuccess(data);
        } catch (Throwable throwable) {
            transferCallback.onError(throwable);
        }
    }

    /**
     * 3.將對(duì)象中的某個(gè)數(shù)據(jù)保存
     */
    public void save(Data data, Callback resultCallback) {
        try {
            ResultBean result = data.getResult();
            ListBean list = result.getList();
            List<TngouBean> tngou = list.getTngou();

            String s = GsonUtils.GsonString(list);
            SharedPreferences config = getSharedPreferences("config", MODE_PRIVATE);
            config.edit().putString("tag", s).apply();

            resultCallback.onSuccess(Uri.parse(s));
        } catch (Throwable e) {
            resultCallback.onError(e);
        }
    }
}

3. 第三步,讓異步方法有返回值绍傲,從而避免嵌套

異步操作是沒有返回值的扔傅,但是我們可以返回一個(gè)可以把傳遞進(jìn)來的參數(shù)變成結(jié)果的步驟(動(dòng)作/Action)

獲得一個(gè)抽象類AsyncJob 這個(gè)AsyncJob 接收一個(gè)Callback ,有一個(gè)start() 的方法


public interface AsyncJob<T> {
    void start(Callback<T> callback);
}

這個(gè)start() 方法就是要執(zhí)行的動(dòng)作,

回到剛才話題

  1. 創(chuàng)建異步任務(wù)的時(shí)候是沒有返回值的
  2. 所以我們要返回一個(gè)含有將傳遞進(jìn)來的參數(shù)轉(zhuǎn)變成結(jié)果的動(dòng)作,AsyncJob 是返回結(jié)果,start()就是動(dòng)作
  3. 啟動(dòng)這個(gè)任務(wù)的時(shí)候需要的這個(gè)Callback中則會(huì)將成功/失敗的結(jié)果傳遞出去

將行為封裝后烫饼,這樣每次執(zhí)行后就可以獲得一個(gè)返回值(這個(gè)返回值實(shí)際上就是一個(gè)方法包裝)

這樣行為的封裝結(jié)果有了猎塞,那么就可以像同步方法一樣執(zhí)行一步一步的操作了;

map/faltMap操作符做了點(diǎn)什么

  1. 使用前/抽離前

    AsyncJob<Model> modelAsyncJob2 = new AsyncJob<Model>() {
      @Override
      public void start(RxCallback<Model> rxCallback) {
       //responseAsyncJob 是上個(gè)AsyncJob對(duì)象
        responseAsyncJob.start(new RxCallback<Response>() {
          @Override
          public void onSuccess(Response response) {
            //除了下面這一行其他都是模板代碼杠纵,所以應(yīng)該抽離出來
            Model convert = convert(response);
            rxCallback.onSuccess(convert);
          }
    
          @Override
          public void onError(Throwable e) {
            rxCallback.onError(e);
          }
        });
      }
    };
    
  2. 使用后/抽離后

    //responseAsyncJob 是上個(gè)AsyncJob對(duì)象
    AsyncJob<Model> modelAsyncJob1 = responseAsyncJob.map(new FunC1<Response, Model>() {
      @Override
      public Model call(Response response) {
        Model model = convert(response);
        return model;
      }
    });
    

    ?

  3. map操作符做了點(diǎn)什么

    public <R> AsyncJob<R> map(FunC1<T, R> funC1) {
      //1. source 就是上一個(gè)資源 (上次對(duì)象)
      AsyncJob<T> source = this;
    
      //2. 這里的new 對(duì)象就是返回的對(duì)象(簡(jiǎn)稱本次對(duì)象)
      return new AsyncJob<R>() {
    
        //3. 這里表示本次執(zhí)行(start())的時(shí)候荠耽,(調(diào)用start方法的時(shí)候,會(huì)去先執(zhí)行上個(gè)對(duì)象的start()方法)
        @Override
        //4. 本個(gè)對(duì)象的start()方法
        public void start(RxCallback<R> callback) {
    
          //5. 上個(gè)對(duì)象start()方法
          source.start(new RxCallback<T>() {
            @Override
            public void onSuccess(T t) {
              //5.5 如果上個(gè)對(duì)象的start方法成功了
              //6.0這里有一個(gè)不確定的函數(shù)淡诗,這個(gè)函數(shù)聲明了將一個(gè)T骇塘,類型的參數(shù)轉(zhuǎn)換為一個(gè)R類型
              R result = funC1.call(t);
              //7 -a將成功結(jié)果傳遞出去
              callback.onSuccess(result);
            }
    
            @Override
            public void onError(Throwable e) {
              //7- b 將結(jié)果傳遞出去
              callback.onError(e);
            }
          });
        }
      };
    }
    
  4. flatMap 做了點(diǎn)什么

    public <R> AsyncJob<R> flatMap(FunC1<T, AsyncJob<R>> funC1) {
      //1. 保存上個(gè)對(duì)象
      AsyncJob<T> source = this;
      //2. 返回本次對(duì)象
      return new AsyncJob<R>() {
        //3. 表示本次對(duì)象執(zhí)行
        @Override
        public void start(RxCallback<R> callback) {
          //4. 表示執(zhí)行時(shí)首先會(huì)執(zhí)行上個(gè)對(duì)象的start()方法
          source.start(new RxCallback<T>() {
            @Override
            public void onSuccess(T t) {
              //5. 在上個(gè)對(duì)象成功中使用傳入的抽象動(dòng)作伊履,將一個(gè)參數(shù)轉(zhuǎn)換為另外一個(gè)AsyncJob對(duì)象
              AsyncJob<R> call = funC1.call(t);
              //6. 調(diào)用這個(gè)AsyncJob對(duì)象的start()方法
              call.start(new RxCallback<R>() {
                @Override
                public void onSuccess(R r) {
                  //7. 在成功時(shí)將結(jié)果傳遞出去
                  callback.onSuccess(r);
                }
    
                @Override
                public void onError(Throwable e) {
                  callback.onError(e);
                }
              });
            }
    
            @Override
            public void onError(Throwable e) {
              callback.onError(e);
            }
          });
        }
      };
    }
    

    ?

  5. mapflatMap 是哪里不一樣韩容?

map 中接收的接口中的泛型是<T,R>

說明map操作符中Func1接口的call方法的返回值是一個(gè)R類型的參數(shù)

  @Override
  public Model call(Response response) {
    Model model = convert(response);
    return model;
  }

?

flatmap 中接收的接口中的泛型是<T,Observable<R>>

說明flatmap 操作符中Func1 接口的call方法的返回值是一個(gè)Observable<R>類型的參數(shù)

@Override
public AsyncJob<Uri> call(Model model) {
  AsyncJob<Uri> save = save(model);
  return save;
}

?

?

封裝完成前后的對(duì)比

沒有進(jìn)行封裝,需要傳遞CallBack的原始方法(含有嵌套操作)

public void getResult(String url, RxCallback<Uri> rxCallback) {
  netApi.get(url, new RxCallback<Response>() {
    @Override
    public void onSuccess(Response response) {
      Model model = convert(response);

      save(model, new RxCallback<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
          rxCallback.onSuccess(uri);
        }

        @Override
        public void onError(Throwable e) {
          rxCallback.onError(e);
        }
      });
    }

    @Override
    public void onError(Throwable e) {
      rxCallback.onError(e);
    }
  });
}

使用封裝了start()函數(shù)后

public AsyncJob<Uri> getResult(String url) {
  AsyncJob<Response> responseAsyncJob = netApi.get(url);
  AsyncJob<Model> modelAsyncJob = new AsyncJob<Model>() {
    @Override
    public void start(RxCallback<Model> rxCallback) {
      responseAsyncJob.start(new RxCallback<Response>() {
        @Override
        public void onSuccess(Response response) {
          Model convert = convert(response);
          rxCallback.onSuccess(convert);
        }

        @Override
        public void onError(Throwable e) {
          rxCallback.onError(e);
        }
      });
    }
  };

  AsyncJob<Uri> uriAsyncJob = new AsyncJob<Uri>() {
    @Override
    public void start(RxCallback<Uri> rxCallback) {
      modelAsyncJob.start(new RxCallback<Model>() {
        @Override
        public void onSuccess(Model model) {
          AsyncJob<Uri> save = save(model);
          save.start(new RxCallback<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
              rxCallback.onSuccess(uri);
            }

            @Override
            public void onError(Throwable e) {
              rxCallback.onError(e);
            }
          });
        }

        @Override
        public void onError(Throwable e) {
          rxCallback.onError(e);
        }
      });
    }
  };
  return uriAsyncJob;       
}

封裝了map操作符 和flatMap 操作符

public AsyncJob<Uri> getResult(String url) {
  AsyncJob<Response> responseAsyncJob = netApi.get(url);
  AsyncJob<Model> modelAsyncJob1 = responseAsyncJob.map(new FunC1<Response, Model>() {
    @Override
    public Model call(Response response) {
      Model model = convert(response);
      return model;
    }
  });
  AsyncJob<Uri> uriAsyncJob = modelAsyncJob1.flatMap(new FunC1<Model, AsyncJob<Uri>>() {
    @Override
    public AsyncJob<Uri> call(Model model) {
      AsyncJob<Uri> save = save(model);
      return save;
    }
  });
}

封裝完成 唐瀑,lambda化后

public AsyncJob<Uri> getResult(String url) {
  return netApi.get(url)
    .map(this::convert)
    .flatMap(this::save);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末群凶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哄辣,更是在濱河造成了極大的恐慌请梢,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件力穗,死亡現(xiàn)場(chǎng)離奇詭異毅弧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)当窗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門够坐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事元咙√萦埃” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵庶香,是天一觀的道長(zhǎng)甲棍。 經(jīng)常有香客問我,道長(zhǎng)赶掖,這世上最難降的妖魔是什么感猛? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮倘零,結(jié)果婚禮上唱遭,老公的妹妹穿的比我還像新娘。我一直安慰自己呈驶,他們只是感情好拷泽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著袖瞻,像睡著了一般司致。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聋迎,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天脂矫,我揣著相機(jī)與錄音,去河邊找鬼霉晕。 笑死庭再,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的牺堰。 我是一名探鬼主播拄轻,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼伟葫!你這毒婦竟也來了恨搓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤筏养,失蹤者是張志新(化名)和其女友劉穎斧抱,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渐溶,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辉浦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茎辐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宪郊。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眉睹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出废膘,到底是詐尸還是另有隱情竹海,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布丐黄,位于F島的核電站斋配,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏灌闺。R本人自食惡果不足惜艰争,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桂对。 院中可真熱鬧甩卓,春花似錦、人聲如沸蕉斜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宅此。三九已至机错,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間父腕,已是汗流浹背弱匪。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留璧亮,地道東北人萧诫。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像枝嘶,于是被迫代替她去往敵國(guó)和親帘饶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 前言我從去年開始使用 RxJava 躬络,到現(xiàn)在一年多了尖奔。今年加入了 Flipboard 后搭儒,看到 Flipboard...
    占導(dǎo)zqq閱讀 9,164評(píng)論 6 151
  • 我從去年開始使用 RxJava 穷当,到現(xiàn)在一年多了。今年加入了 Flipboard 后淹禾,看到 Flipboard 的...
    Jason_andy閱讀 5,484評(píng)論 7 62
  • 前言RxJava和Retrofit也火了一段時(shí)間了馁菜,不過最近一直在學(xué)習(xí)ReactNative和Node相關(guān)的姿勢(shì),...
    AFinalStone閱讀 555評(píng)論 0 0
  • 文章轉(zhuǎn)自:http://gank.io/post/560e15be2dca930e00da1083作者:扔物線在正...
    xpengb閱讀 7,034評(píng)論 9 73
  • 古時(shí)候的人铃岔,晚上出門一定很不方便汪疮,沒有整晚明晃晃的便捷的路燈峭火,只有一盞紙糊的素色燈籠,風(fēng)雨飄搖智嚷。若是家貧卖丸,無以立足...
    Hebetow閱讀 230評(píng)論 0 3