上一篇Android 网络请求框架总结(一)总结了一些我在Android网络请求解析这一块的一些经验,过程是循序渐进的,从无到有,从不完善到完善,这一篇将继续优化以上的代码,看看还有哪些需要做的,地址,参数,回调,网络判断,请求状态判断,json解析,错误信息收集都有了,看似没有什么问题,还是结合实际的问题来分析,在很早的一个项目中我发现了一个问题,而且是在网络状态很差,我快速切换页面的时候才会出现,症状大概是这样,进去一个页面,发出了网络请求,我耐心的等待数据的加载完成,再出去另一个页面去请求另一个数据,根本就加载不出来,退出应用出去再进就好了,当时的网络请求框架是当时公司的技术总监写的,我大概看了下源码,就简单的封装了一个异步任务(AsyncTask),发现了请求是不能取消的,那就意味着当页面销毁的时候请求并没有取消,才导致的我上面描述的bug,继续优化代码

public class HttpClient {    public static RequestQueue queue = Volley.newRequestQueue(App.getContext());    public static final String RESULT_CODE = "code"; //状态码,后台返回成功或者失败    public static final String RETURN_MESSAGE = "message";//消息,后台返回的文本消息,提示或者错误信息    public static final String RESULT = "result";//成功的返回结果    public static final String SUCCESS = "1"; //成功    public static final String FAILURE = "0";//失败    public static void postRequest(Context context, String url, final Map<String, String> map, final OnResponseListener listener) {        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {            @Override            public void onResponse(String response) {                try {                    JSONObject jsonObject = new JSONObject(response);//将json数据转化为json对象                    if (!jsonObject.isNull(RESULT_CODE)) {//判断code字段是否存在                        String code = jsonObject.getString(RESULT_CODE);//活得code的值                        if (code.equals(SUCCESS)) { //成功则继续往下判断                            if (!jsonObject.isNull(RESULT)) {                                String result = jsonObject.getString(RESULT);                                listener.success(result);                            }                        } else if (code.equals(FAILURE)) {//失败返回错误信息                            if (!jsonObject.isNull(RETURN_MESSAGE)) {//判断message字段是否存在                                listener.failure(jsonObject.getString(RETURN_MESSAGE));//返回后台失败信息                            }                        } else {                            listener.failure("无效的状态码");//返回状态码无效的错误信息                        }                    } else {                        listener.failure("状态码不存在");//返回状态码不存在的错误信息                    }                } catch (JSONException e) {                    e.printStackTrace();                    listener.failure(e.getLocalizedMessage());//返回json异常的错误信息                }                listener.success(response);            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                listener.failure(error.getLocalizedMessage());//返回Volley异常的错误信息            }        }) {            @Override            protected Map<String, String> getParams() throws AuthFailureError {                return map;            }        };        //判断网络是否连接        if (NetworkUtils.isConnectedByState(App.getContext())) {            addRequest(request, context);//将请求添加到队列        } else {            listener.failure("网络未连接");//返回网络未连接的错误信息        }    }    /** * 添加请求到请求队列中 * * @param request 请求 * @param tag 目标对象,Activity或者Fragment */    private static void addRequest(Request<?> request, Object tag) {        if (tag != null) {            request.setTag(tag);        }        queue.add(request);    }    /** * 取消目标对象中的所有请求 * * @param tag 目标对象,Activity或者Fragment */    public static void cancelRequest(Object tag) {        queue.cancelAll(tag);    }

使用

 /** * Activity销毁的时候取消该Activity的所有请求 */    @Override    protected void onDestroy() {        super.onDestroy();        HttpClient.cancelRequest(this);    } /** * Fragment 视图销毁的时候取消该Fragment的所有网络请求 */    @Override    public void onDestroyView() {        super.onDestroyView();        HttpClient.cancelRequest(this);    } Map<String,String> map = new HashMap<>();        map.put("key1","value1");        map.put("key2", "value1");    HttpClient.postRequest(this,"http://www.baidu.com", map, new OnResponseListener() {            @Override            public void success(String result) {                System.out.println("result = " + result);                //这里我新建了一个测试的对象,采用了gson来将json数据转换为bean对象                //解析成对象,嵌套的对象也是可以的                TestBean testBean = new Gson().fromJson(result, TestBean.class);                //解析成list                Type type = new TypeToken<ArrayList<TestBean>>() {                }.getType();                List<TestBean> testBeans = new Gson().fromJson(result, type);                //解析成数组                TestBean[] testBeans1 = new Gson().fromJson(result, TestBean[].class);                //这个时候想转化为list可以调用下面的方法                List<TestBean> testBeans2 = Arrays.asList(testBeans1);            }            @Override            public void failure(String errorMessage) {                System.out.println("errorMessage = " + errorMessage);            }        });

继续走,看看这个框架还可以做哪些事情,上一篇讲了关于gson解析相关的内容,注释比较详细,应该可以满足基本的需求,问题就是每次都要手动解析,使用起来还是显得有些麻烦,可以在框架中自动解析Json数,使用的时候直接拿到对象操作就行了,我们尝试下

先改一下接口

public interface OnResponseListener {    void success(Object result);    void failure(String errorMessage);}

HttpClient.java

public class HttpClient {    public static RequestQueue queue = Volley.newRequestQueue(App.getContext());    public static final String RESULT_CODE = "code"; //状态码,后台返回成功或者失败    public static final String RETURN_MESSAGE = "message";//消息,后台返回的文本消息,提示或者错误信息    public static final String RESULT = "result";//成功的返回结果    public static final String SUCCESS = "1"; //成功    public static final String FAILURE = "0";//失败    public static void postRequest(Context context, String url, final Class clazz, final Map<String, String> map, final OnResponseListener listener) {        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {            @Override            public void onResponse(String response) {                try {                    JSONObject jsonObject = new JSONObject(response);//将json数据转化为json对象                    if (!jsonObject.isNull(RESULT_CODE)) {//判断code字段是否存在                        String code = jsonObject.getString(RESULT_CODE);//活得code的值                        if (code.equals(SUCCESS)) { //成功则继续往下判断                            if (!jsonObject.isNull(RESULT)) {                                String result = jsonObject.getString(RESULT);                                Object o;                                if (result.charAt(0) == '{') {                                    //解析对象                                    o = new Gson().fromJson(result, clazz);                                } else {                                    //这个方法是在stackoverflow中找到的可将json转换为list,普通的通过type去解析是不行的                                    o = new Gson().fromJson(result, com.google.gson.internal.$Gson$Types.newParameterizedTypeWithOwner(null, ArrayList.class, clazz));                                }                                listener.success(o);                            }                        } else if (code.equals(FAILURE)) {//失败返回错误信息                            if (!jsonObject.isNull(RETURN_MESSAGE)) {//判断message字段是否存在                                listener.failure(jsonObject.getString(RETURN_MESSAGE));//返回后台失败信息                            }                        } else {                            listener.failure("无效的状态码");//返回状态码无效的错误信息                        }                    } else {                        listener.failure("状态码不存在");//返回状态码不存在的错误信息                    }                } catch (JSONException e) {                    e.printStackTrace();                    listener.failure(e.getLocalizedMessage());//返回json异常的错误信息                }                listener.success(response);            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                listener.failure(error.getLocalizedMessage());//返回Volley异常的错误信息            }        }) {            @Override            protected Map<String, String> getParams() throws AuthFailureError {                return map;            }        };        //判断网络是否连接        if (NetworkUtils.isConnectedByState(App.getContext())) {            addRequest(request, context);//将请求添加到队列        } else {            listener.failure("网络未连接");//返回网络未连接的错误信息        }    }    /** * 添加请求到请求队列中 * * @param request 请求 * @param tag 目标对象,Activity或者Fragment */    private static void addRequest(Request<?> request, Object tag) {        if (tag != null) {            request.setTag(tag);        }        queue.add(request);    }    /** * 取消目标对象中的所有请求,在Activity或者Fragment销毁的时候调用 * * @param tag 目标对象,Activity或者Fragment */    public static void cancelRequest(Object tag) {        queue.cancelAll(tag);    }

使用

HttpClient.postRequest(this, "http://www.baidu.com", TestBean.class, map, new OnResponseListener() {            @Override            public void success(Object result) {                //如果result为对象                TestBean testBean = ((TestBean) result);                //如果result为list                List<TestBean> testBeans = (ArrayList<TestBean>) result;            }            @Override            public void failure(String errorMessage) {                System.out.println("errorMessage = " + errorMessage);            }        });

这样就完成了自动解析json的过程,调用的时候强转一下对象的类型就行了

重新封装的框架的好处还有很多,可以打印每次请求和响应的数据,批量处理空值,还可以在这里进行数据缓存,包括后期的一些扩展都很方便

更多相关文章

  1. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
  2. 使用android真机测试http网络连接异常解决办法
  3. Android之socket
  4. Handler ThreadHandler Looper的总结
  5. Android中activity和xml的第一个项目
  6. Android中将xml布局文件转化为View树的过程分析(上)
  7. Android常见面试题&字节跳动、阿里、腾讯2019实习生Android岗部
  8. [置顶] Android(安卓)Binder跨进程与非跨进程的传输异同源码分析
  9. 重温String和StringBuffer

随机推荐

  1. 蓝牙通讯开发记录
  2. Android(安卓)SQLite Database
  3. Android(安卓)DOC翻译—Processes and Th
  4. adb tools
  5. android.graphics.Paint类详解
  6. Android开源项目分类汇总
  7. Java中HashMap如何工作的?
  8. android 管理wifi
  9. Google cardBoard Android(安卓)API (六)
  10. Google cardBoard Android(安卓)API (二)