Android-Retrofit2+Rxjava2之网络通用请求-初步封装-完善优化数据【对象】请求

上一篇我们进行了初步封装的总结,同时针对分页列表的请求做了简单的调用请求处理。这篇我们接着调用BaseControlPresenter的requestData方法获取数据【对象】 - 非列表的方式。

1. 创建服务

    private BaseControlContract.Presenter presenter;
    ///< 创建请求服务
    presenter = new BaseControlPresenter<String>(this, new BaseControlPresenter.DataHandler<String>() {
            @Override
            public String String2Data(String strData) {
                return strData;
            }
        });

2. 发起请求

 ///< 获取钱包地址
 presenter.requestData("eth-addr", null);

 ///< 领取糖果
 HashMap<String, String> paramsList = new HashMap<>();
 paramsList.put("id", candyId + "");
 paramsList.put("eth_address", walletAddr.getText().toString().trim());
 presenter.requestData("receive-candy-detail", paramsList);

3. 成功回调

    @Override
    public <T> void onSucess(T t) {
        String str = (String) t;
        if (str.contains("eth_address")) {
            CandyBean.ethAddr ethAddr = JSON.parseObject(str, new TypeReference<CandyBean.ethAddr>() {
            });
            walletAddr.setText(ethAddr.getEth_address());
        } else if (str.contains("content") || str.contains("msg")) {
            CandyBean.ethSuccess ethSuccess = JSON.parseObject(str, new TypeReference<CandyBean.ethSuccess>() {
            });
            walletAddr.setVisibility(View.GONE);
            receiveRoot.setVisibility(View.VISIBLE);
            successTip.setText(ethSuccess.getMsg());
            invationokWv.loadDataWithBaseURL(null, ethSuccess.getContent(), "text/html", "utf-8", null);
        }
    }

分析一下:

1. 解析返回还是String return strData;

2. 请求参数为null?

3. onSucess(T t)中进行Json处理?

为什么这个感觉有点麻烦,1. 一方面没有提前做Json解析,2. 而且我们之前的方法貌似传null有问题,但是确实这个请求方法没有参数。3. 另外onSuccess中根据返回字符串分别进行了解析,貌似有点麻烦,而且位置也不好,提前处理就好了!

解决:问题2我们修改下我们之前的请求方法的部分代码requestData(...)

image

问题1和问题3 (目前这样没有问题,但是我还是想把数据解析提前做,放到io线程中进行处理)。为什么onSuccess中我们进行了分别处理,因为这个页面有多个网络请求,而我们的通用请求只有一个回调,再多搞回调感觉也没必要。

但是如果只创建一个服务的情况下,数据解析返回的类型最多只能定义一个:

image

这样另外一个对象就没办法作为泛型类型了,如下

image

那小白就想,有没有好点的方式,小白想了下,针对目前的页面来讲:

1. 可以只定义实体类,把两个网络请求json的字段全部包含,然后进行转换;使用时判断某个字段是否为空,进而区分应该取哪些字段。

2. 另外一种就是返回类型修改为Object, 然后onSuccess中instanceof判断是哪个对象类型,进而获取数据进行显示。

拿第二种来看:

      ///< 创建请求服务
        presenter = new BaseControlPresenter<Object>(this, new BaseControlPresenter.DataHandler<Object>() {
            @Override
            public Object String2Data(String strData) {
                if (strData.contains("eth_address")) {
                    CandyBean.ethAddr ethAddr = JSON.parseObject(strData, new TypeReference<CandyBean.ethAddr>() {
                    });
                    return ethAddr;
                } else if (strData.contains("content") || strData.contains("msg")) {
                    CandyBean.ethSuccess ethSuccess = JSON.parseObject(strData, new TypeReference<CandyBean.ethSuccess>() {
                    });
                    return ethSuccess;
                }
                return null;
            }
        });

回调时:

    @Override
    public <T> void onSucess(T t) {
        if (t instanceof CandyBean.ethAddr){
            CandyBean.ethAddr ethAddr = (CandyBean.ethAddr) t;
            walletAddr.setText(ethAddr.getEth_address());
        }else if (t instanceof CandyBean.ethSuccess){
            CandyBean.ethSuccess ethSuccess = (CandyBean.ethSuccess) t;
            walletAddr.setVisibility(View.GONE);
            receiveRoot.setVisibility(View.VISIBLE);
            successTip.setText(ethSuccess.getMsg());
            invationokWv.loadDataWithBaseURL(null, ethSuccess.getContent(), "text/html", "utf-8", null);
        }
    }

再拿第一种来看:

完善实体类

CandyBean.java

@NotProguard
public class CandyBean {
    /**
     * eth_address : 0xCAb8eEA4799a21379c20eF5Bba2CC8bF1bEC475B
     */

    private String eth_address;
    /**
     * content : <p>1</p>
     * msg : 领取成功!共领取3.95个test
     */

    private String content;
    private String msg;

    public CandyBean(){}
    public String getEth_address() {
        return eth_address;
    }

    public void setEth_address(String eth_address) {
        this.eth_address = eth_address;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @NotProguard
    public static class ethAddr{
        /**
         * eth_address : 0xCAb8eEA4799a21379c20eF5Bba2CC8bF1bEC475B
         */

        private String eth_address;

        public ethAddr(){}
        public String getEth_address() {
            return eth_address;
        }

        public void setEth_address(String eth_address) {
            this.eth_address = eth_address;
        }
    }

    @NotProguard
    public static class ethSuccess{

        /**
         * content : <p>1</p>
         * msg : 领取成功!共领取3.95个test
         */

        private String content;
        private String msg;

        public ethSuccess(){}
        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
}

请求json解析

   ///< 创建请求服务
        presenter = new BaseControlPresenter<CandyBean>(this, new BaseControlPresenter.DataHandler<CandyBean>() {
            @Override
            public CandyBean String2Data(String strData) {
                return  JSON.parseObject(strData, new TypeReference<CandyBean>() {});
            }
        });

然后回调处理

   @Override
    public <T> void onSucess(T t) {
        CandyBean candyBean = (CandyBean) t;
        if (null != candyBean.getEth_address() && !candyBean.getEth_address().contains("")){
            walletAddr.setText(candyBean.getEth_address());
        }else{
            walletAddr.setVisibility(View.GONE);
            receiveRoot.setVisibility(View.VISIBLE);
            successTip.setText(candyBean.getMsg());
            invationokWv.loadDataWithBaseURL(null, candyBean.getContent(), "text/html", "utf-8", null);
        }
    }

讲真的,从上面看还是第一种方式代码量,什么的要简洁些,而且也不必要定义另外两个对象。当然这只是这种情况,有些请求数据差异特别大的,而且关联性不强的,没有必要搞一个实体类了,那样混合起来不好看!

小白想,其实还有一种方式,就是请求的时候传入JSON解析处理回调,那里给泛型类型,就能解析返回想要的类型(不用去做类型区分啥的):

   /**
         * 请求数据【对象】
         * @param _funUrl
         * @param _paramList
         */
        <T>void requestDataSB(final String _funUrl, HashMap<String, String> _paramList, BaseControlPresenter.DataHandler<T> _dataHandler);

请求

presenter.<CandyBean.ethAddr>requestDataSB("eth-addr", null, new BaseControlPresenter.DataHandler<CandyBean.ethAddr>() {
            @Override
            public CandyBean.ethAddr String2Data(String strData) {
                return JSON.parseObject(strData, new TypeReference<CandyBean.ethAddr>() {});
            }
        });

回调的地方判断下属于哪个类型对象就可以进行强转处理了...

或许还有更好的方案,希望可以赐教!

小白还想考虑把这个请求的url能不能统一管理? 同时转换的地方能不能也做个统一管理?请求url统一管理很有必要,毕竟之后可能要升级,要修改啥的!

统一管理url,小白想这样搞:搞一个管理类,然后通过静态hashmap进行存储,存储的key则是请求的实体类类类型, value就是方法字符串

NetUrlManager.java

import com.x.finance.bean.CandyBean;

import java.util.HashMap;

public class NetUrlManager {
    private static HashMap<Class, String> classStringHashMap = new HashMap<Class, String>() {
        {
            put(CandyBean.ethAddr.class, "eth-addr");
            put(CandyBean.ethSuccess.class, "receive-candy-detail");
        }
    };

    public static String getFunUrl(Class _class) {
        return classStringHashMap.get(_class);
    }
}

然后在requestData调用传递的方法字符串修改为传递实体类类类型

   ///< 获取钱包地址
   presenter.requestData(CandyBean.ethAddr.class, null);

   ///< 领取糖果
   HashMap<String, String> paramsList = new HashMap<>();
   paramsList.put("id", candyId + "");
   paramsList.put("eth_address", walletAddr.getText().toString().trim());
   presenter.requestData(CandyBean.ethSuccess.class, paramsList);

然后requestData里面处理下

image

这样就统一做了下处理。不然字符串方法作为参数很难管理和维护。

小白又想?既然实体类的Class类型都作为参数传入了,那么同样我们解析是不是也可以通过类似的管理方式进行统一管理?getBean

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.x.finance.bean.CandyBean;

import java.util.HashMap;

/*
*@Description: 方法url管理+类型转换管理
*@Author: hl
*@Time: 2018/11/22 16:18
*/
public class NetUrlManager {
    private static HashMap<Class, String> classStringHashMap = new HashMap<Class, String>() {
        {
            put(CandyBean.ethAddr.class, "eth-addr");
            put(CandyBean.ethSuccess.class, "receive-candy-detail");
        }
    };

    private static HashMap<Class, Class> classClassHashMap = new HashMap<Class, Class>() {
        {
            put(CandyBean.ethAddr.class, CandyBean.ethAddr.class);
            put(CandyBean.ethSuccess.class,  CandyBean.ethSuccess.class);
        }
    };

    public static String getFunUrl(Class _class) {
        return classStringHashMap.get(_class);
    }

    public static Object getBean(String strData, Class _class) {
        if (_class.getName().equals(CandyBean.ethAddr.class.getName())){
            return JSON.parseObject(strData, new TypeReference<CandyBean.ethAddr>() {});
        }else if (_class.getName().equals(CandyBean.ethSuccess.class.getName())){
            return JSON.parseObject(strData, new TypeReference<CandyBean.ethSuccess>() {});
        }
        return null;
    }
}

然后BaseControlPresenter里面盗用下

image

这样下来,我们的视图里面创建服务时的回调就不用传了....(记得把构造函数private修改为public)

image

省去了很多麻烦,也方便管理维护。。不过我们的每个请求就需要对应一个对象(其实小白认为这也可以,每个请求一个对象也没啥,也方便管理)。另外回调的地方也判断下类型进行处理:

    @Override
    public <T> void onSucess(T t) {
        if (t instanceof CandyBean.ethAddr){
            CandyBean.ethAddr ethAddr = (CandyBean.ethAddr) t;
            walletAddr.setText(ethAddr.getEth_address());
        }else if (t instanceof CandyBean.ethSuccess){
            CandyBean.ethSuccess ethSuccess = (CandyBean.ethSuccess) t;
            walletAddr.setVisibility(View.GONE);
            receiveRoot.setVisibility(View.VISIBLE);
            successTip.setText(ethSuccess.getMsg());
            invationokWv.loadDataWithBaseURL(null, ethSuccess.getContent(), "text/html", "utf-8", null);
        }
    }

其实也还好,总得来说还是节省了代码,易用性也增加了。

行吧,初步封装可能就先到这里了。还有别的学习任务需要尽快跟上。小白体会到了设计模式,泛型,接口等需要综合熟练的使用才能搞出好的封装。看了泛型,json解析这块还得加深原理的性的东西才行! - 最后列表请求的方式也可以这样优化下哈.....自己搞搞就好了...sb,sb,sb, sb, 酷酷滴....

如果有好的建议,希望能教教小白,感谢! Next, let's hold on......

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容

  • 一直也是用MVP模式,也就结合Rx做网络请求,Rx子线程和UI线程的切换是相当的方便(小白后面准备看下相关的切换的...
    MonkeyLei阅读 596评论 0 1
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,105评论 1 32
  • OkGo,一个专注于让网络请求更简单的框架,与RxJava完美结合,比Retrofit更简单易用。 OkGo - ...
    压抑的内心阅读 16,475评论 0 9
  • 故乡,这一抔湿润的泥土 养育了我懵懂的童年 潺潺的流水 带走了时间 冲刷了儿时的记忆 有的时候 它在我脑海里 若隐...
    ZZOOzzoo阅读 328评论 0 4
  • 秋雨一场消夏念,今朝复来四面寒。 雷闪霹雳震窗碎,飞沙急走撞丛间。 墨云劲翻千层浪,号风呼卷万仞山。 风定潮气升天...
    刘玘阔阅读 155评论 0 0