Retrofit2+Rxjava2的Rxjava2中flatmap使用

首先简单了解一下map和flatmap的区别:

map:解决请求过程中,数据变换的操作,比如:请求到的结果是1、3、5,而我要的是2、6、10,很显然就是要结果的双倍,所以用map操作符处理一下,让他返回value*2。

flatmap:解决嵌套网络请求,比如:我先要请求拿到所有的学生的学号,然后再根据每个学号去请求拿到每个学生对应的姓名。你还可以再复杂一点,再根据每个学生的姓名中的姓,再去请求拿到所有这个姓氏的学生的List。

 

而这一篇文章,就来举例说明一下flatmap的使用。

应用场景:

咱再举两个例子:

1、接口请求拿到所有城市,然后再根据拿到的城市的编码再去请求接口拿到每个城市的温度。

2、接口请求判断这个账号是否已注册,若已注册再去请求判断密码是否正确。

当然,这些东西后台全都可以搞定归结成一个接口给你,但是后台人员比较固执的话……我们前端也是可以搞的。

举例需求:

根据酷狗的搜索接口:http://mobilecdn.kugou.com/api/v3/search/song?format=json&keyword=歌名&page=1&pagesize=20 搜得歌曲列表,然后根据每个歌曲的hash值再去接口:http://m.kugou.com/app/i/getSongInfo.php?cmd=playInfo&hash=上面搜索的歌曲的hash值 中请求拿到歌曲的详情(包括专辑图链接和歌曲播放链接)。

 

接口的配置想必大家都会了,这里因为两个接口的域名不同,我们挑其中一个比较特殊的给一个全路径:

public interface ApiService {

    /**
     * 酷狗搜索接口
     */
    @GET("http://mobilecdn.kugou.com/api/v3/search/song?format=json")
    Observable<KugouSearch> searchKugou(@QueryMap Map<String,Object> map);

    /**
     * 酷狗音乐详情
     * @param hash 歌曲的hash
     * @return 详情
     */
    @FormUrlEncoded
    @POST("app/i/getSongInfo.php?cmd=playInfo")
    Observable<KugouDetail> getDetail(@Field("hash") String hash);

}

搜索接口给了全路径,那详情接口的域名“http://m.kugou.com/”就配置到baseUrl里面了。

至于这两个实体类太长了,我简单说一下:

KugouSearch:里面包含了我们歌曲列表,然后歌曲列表的每一项里面有一个我们想要的hash值,类似这项的id吧。

KugouDetail:里面包含专辑图链接和歌曲播放链接,这些是我们想要的详情,是搜索的结果里面没有的。

具体看文章末给的demo链接,就不列出来了。

 

我们直接看重点,flatmap的使用:

Map<String,Object> map = new HashMap<>();
map.put("keyword",name);
map.put("page",page);
map.put("pagesize", BaseConstant.PAGE_SIZE);
Api.getApiService().searchKugou(map)
        //搜索请求的结果,把他的歌曲列表拿出来遍历
        .flatMap(new Function<KugouSearch, Observable<KugouSearch.DataBean.InfoBean>>() {
            @Override
            public Observable<KugouSearch.DataBean.InfoBean> apply(KugouSearch kugouSearch) throws Exception {
                //kugouSearch.getData().getInfo()是List类型,就是搜索出来的全部歌曲的列表
                return Observable.fromIterable(kugouSearch.getData().getInfo());
            }
        })
        //根据上面遍历的每一个歌曲,拿它的hash值
        .flatMap(new Function<KugouSearch.DataBean.InfoBean, ObservableSource<KugouDetail>>() {
            @Override
            public ObservableSource<KugouDetail> apply(KugouSearch.DataBean.InfoBean infoBean) throws Exception {
                //获取歌曲详情的请求,传hash给第二个接口,拿到详情
                return Api.getApiService().getDetail(infoBean.getHash());
            }
        })
        //因为获取详情的接口只是获取一首歌的,我们要的是搜索到的所有歌曲的每首歌的详情
        //toList可以转化成List<KugouDetail>
        .toList()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new SingleObserver<List<KugouDetail>>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onSuccess(List<KugouDetail> value) {
                //这样就拿到了我们想要的二次请求的数据了
                getV().showData(value);
            }

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

 

Demo链接:GitHub。参照SearchDetailPresenter类

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值