OkGo3.0真实项目使用和二次封装

前言

之前使用okhttputil,由于鸿洋的该框架并未对于回调数据进行过度处理,callback需要自定义处理,所以在项目使用时对其进行了封装,后来发现OkGo对于Callback进行了封装,自己的封装Callback和OkGo的有些相似,然后在新的项目中就使用基于OkGo二次封装的网络请求框架了,这里主要介绍OkGo的基于MVC下的二次封装和使用

本文案例的项目地址 https://github.com/caixingcun/OkGoDemo

OkGo地址 https://github.com/jeasonlzy/okhttp-OkGo/wiki
OkHttpUtil 地址 https://github.com/hongyangAndroid/okhttputils

分析

现在的网络框架正常都是使用的json从后台获取数据,这里保存RESTful风格
这里需要首先跟后台约定好传递数据的格式
常规数据格式

{
    "Code":100,
    "Msg":"请求成功",
    "Result":{
        "Name":"老王"
    }
}

常规错误数据格式

{
    "Code":101,
    "Msg":"请求失败",
}

数组数据

{
    "Code":100,
    "Msg":"请求成功",
    "Result":[
        {
            "Name":"老王",
            "Age":23
        },
        {
            "Name":"老李",
            "Age":25
        }
    ]
}

数组请求为空
{
“Code”:100,
“Msg”:”请求成功”,
“Result”:[]
}

OkGo的集成

1.添加依赖
compile ‘com.readystatesoftware.chuck:library:1.0.4’
compile ‘com.readystatesoftware.chuck:library:1.0.4’
2.App中初始化
有特定需求的可以按okgo文档配置

      OkGo.getInstance().init(this);

3.下载OkGo案例
OkGo3.0真实项目使用和二次封装_第1张图片

将demo下callback中的内容复制进自己的项目
这部分是作者编写的可供修改的框架部分
OkGo3.0真实项目使用和二次封装_第2张图片
有报错基本就是类不存,或者重写import
把相关类复制进来

可以看一下当前复制进来的主要几个类
Convert.java 转换
JsonConvert.java 带泛型转换
JsonCallback.java 泛型转换回调

LzyResponse.java 实体类
SimpleResponse.java

顾名思义 也可以看出这些类的大概意思
基本上Convert就是基本的Gson转换
OkGo3.0真实项目使用和二次封装_第3张图片

JsonConvert就是再上面的基础上对于网络请求数据进行了初步处理
这里已经在分析返回错误码
也就是我们最上面定义的{“Code”:101,”Msg”:”“}
OkGo3.0真实项目使用和二次封装_第4张图片
我们来看一下作者的转换类 LzyResponse.java
OkGo3.0真实项目使用和二次封装_第5张图片
基本格式实际上是跟我们统一的

再看一下JsonCallback.java
应该是对于传递的泛型进行分类型处理
OkGo3.0真实项目使用和二次封装_第6张图片
OkGo3.0真实项目使用和二次封装_第7张图片

OkGo的修改

我这里先使用node.js创建一个本地简易网络访问服务器
创建一组json请求数据
OkGo3.0真实项目使用和二次封装_第8张图片

        OkGo.<String>get("http://192.168.1.79:3000/simplerequest")
                .execute(new StringCallback(){
                    @Override
                    public void onSuccess(Response<String> response) {
                        tv.setText(response.body());
                    }
                });

注意上面的是大写的Code
下面添加一串跟OkGo中Lzy相同的数据结构,并请求

OkGo3.0真实项目使用和二次封装_第9张图片
代码

      OkGo.get("http://192.168.1.79:3000/okgoget")
                .execute(new JsonCallback() {
                    @Override
                    public void onSuccess(Response response) {
                        tv.setText(response.body().msg);
                    }
                });

整改开始,就是将作者所给框架的code msg修改为跟我们后台约定一样的格式
改了LzyResponse和SimpleResponse,JsonConvert就可以了,很快
再来通过作者的二次框架来访问大写Code Msg

OkGo3.0真实项目使用和二次封装_第10张图片
基本上能用了

但是要知道为什么自己要进行二次封装网络框架
正常的StringCallback也可以进行网络请求,就是因为方便
这里需要使用LzyResponse
然后对于JsonConvert和JsonCallback进行整改

当我们使用LzyRespose接收数据时,会发现我们拿不到我们的数据,在Callback回调中
数据

{"Code":104,"Msg":"授权无效"}

代码

     OkGo.>get("http://192.168.1.79:3000/okgo104")
                .execute(new JsonCallback>(){
                    @Override
                    public void onSuccess(Response> response) {
                        tv.setText(response.body().Msg+response.body().Code);
                    }
              });

在访问后台总会发生各种问题,尤其时身份问题
还有各种错误,这些东西需要统一处理

看下JsonConvert的源码

                int code = lzyResponse.Code;
                //这里的0是以下意思
                //一般来说服务器会和客户端约定一个数表示成功,其余的表示失败,这里根据实际情况修改
                if (code == 0) {
                    //noinspection unchecked
                    return (T) lzyResponse;
                } else if (code == 104) {
                    throw new IllegalStateException("用户授权信息无效");
                } else if (code == 105) {
                    throw new IllegalStateException("用户收取信息已过期");
                } else {
                    //直接将服务端的错误信息抛出,onError中可以获取
                    throw new IllegalStateException("错误代码:" + code + ",错误信息:" + lzyResponse.Msg);
                }

我们在这里只需要将和后台约定的Code状况都添加进来
也可以像我之前的代码
抛出自定义异常 然后统一到onError中处理

         int code = responseBean.Code;
                String msg = responseBean.Msg;
                //这里的0是以下意思
                //一般来说服务器会和客户端约定一个数表示成功,其余的表示失败,这里根据实际情况修改
                //这里的异常会抛到 JsonCallback中 的onError
                if (code == 0 || code == 103) {
                    //noinspection unchecked
                       return (T) responseBean;
                } else {
                    throw new MyException("{\"Code\":"+code+",\"Msg\":\""+msg+"\"}");
                }

在JsonCallback中重写onError进行异常处理
需要注意onError回调中response.code()是网络请求的code
不是我们数据中的code

        if (code == 100) {
                    return (T) lzyResponse;
                } else {
                    throw new MyException("{\"Code\":"+code+",\"Msg\":\""+msg+"\"}");
                }

MyException

public class MyException extends IllegalStateException {

    private LzyResponse errorBean;

    public MyException(String s) {
        super(s);
        errorBean = new Gson().fromJson(s, LzyResponse.class);
    }

    public LzyResponse getErrorBean() {
        return errorBean;
    }
}

JsonCallback中 onError

    @Override
    public void onError(com.lzy.okgo.model.Response response) {
        super.onError(response);
        int code = response.code();
        if (code == 404) {
            Log.d("JsonCallback", "404 当前链接不存在");
        }
        if (response.getException() instanceof SocketTimeoutException) {
            Log.d("JsonCallback", "请求超时");
        } else if (response.getException() instanceof SocketException) {
            Log.d("JsonCallback", "服务器异常");
        } else if (response.getException() instanceof MyException) {
            switch (((MyException) response.getException()).getErrorBean().Code) {
                case 107: //约定的身份表示过期
                    //重登录
                    break;
            }

        }
    }

对于回调封装到这里就结束了

外部调用简单封装

public class OkGoUtil {
    public static <T> void getRequets(String url, Object tag, Map<String, String> map, JsonCallback<T> callback) {
        // TODO: 2017/10/13  加密 时间戳等 请求日志打印
        Log.d("OkGoUtil", "method get");
        OkGo.<T>get(url)
                .tag(tag)
                .params(map)
                .execute(callback);
    }
    public static <T> void postRequest(String url, Object tag, Map<String, String> map, JsonCallback<T> callback) {
        // TODO: 2017/10/13  加密 时间戳等 请求日志打印
        Log.d("OkGoUtil", "method post");
        OkGo.<T>post(url)
                .tag(tag)
                .params(map)
                .execute(callback);
    }
}

最后

来看一下调用情况

接口
http://localhost:3000/api/post
数据
{"Code":100,
"Msg":"请求成功",
"Result":{"name":"老王","hobby":"爱吃鸡"}
}

新建数据bean

public class SimpleBean {
    /**
     * name : 老王
     * habby : 吃鸡
     */

    private String name;
    private String habby;

}

get set方法这里不贴

请求

      OkGoUtil.getRequets("http://192.168.1.79:3000/okgo_get", this, new HashMap<String, String>(), new JsonCallback>() {
            @Override
            public void onSuccess(Response> response) {
                tv.setText(response.body().Result.getName() + "-" + response.body().Result.getHabby());
            }
        });

最终结果
OkGo3.0真实项目使用和二次封装_第11张图片

好了封装完毕

之后每次使用 只需要将Result中数据bean创建出来
其他所有异常 在与后台约定好后通过Code 在JsonCallback中的onError中进行处理即可

在onSuccess中只处理 Code = 100的正常情况

如果有需要在主线程需要做什么特殊处理
在调用时的Callback中重写onError也是可以拿到具体的错误数据的

你可能感兴趣的:(android)