Android 网络请求框架总结(二)
2015-08-04 23:08
507 查看
上一篇Android 网络请求框架总结(一)总结了一些我在Android网络请求解析这一块的一些经验,过程是循序渐进的,从无到有,从不完善到完善,这一篇将继续优化以上的代码,看看还有哪些需要做的,地址,参数,回调,网络判断,请求状态判断,json解析,错误信息收集都有了,看似没有什么问题,还是结合实际的问题来分析,在很早的一个项目中我发现了一个问题,而且是在网络状态很差,我快速切换页面的时候才会出现,症状大概是这样,进去一个页面,发出了网络请求,我耐心的等待数据的加载完成,再出去另一个页面去请求另一个数据,根本就加载不出来,退出应用出去再进就好了,当时的网络请求框架是当时公司的技术总监写的,我大概看了下源码,就简单的封装了一个异步任务(AsyncTask),发现了请求是不能取消的,那就意味着当页面销毁的时候请求并没有取消,才导致的我上面描述的bug,继续优化代码
使用
继续走,看看这个框架还可以做哪些事情,上一篇讲了关于gson解析相关的内容,注释比较详细,应该可以满足基本的需求,问题就是每次都要手动解析,使用起来还是显得有些麻烦,可以在框架中自动解析Json数,使用的时候直接拿到对象操作就行了,我们尝试下
先改一下接口
HttpClient.java
使用
这样就完成了自动解析json的过程,调用的时候强转一下对象的类型就行了
重新封装的框架的好处还有很多,可以打印每次请求和响应的数据,批量处理空值,还可以在这里进行数据缓存,包括后期的一些扩展都很方便
[code]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); }
使用
[code] /** * 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数,使用的时候直接拿到对象操作就行了,我们尝试下
先改一下接口
[code]public interface OnResponseListener { void success(Object result); void failure(String errorMessage); }
HttpClient.java
[code]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); }
使用
[code]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的过程,调用的时候强转一下对象的类型就行了
重新封装的框架的好处还有很多,可以打印每次请求和响应的数据,批量处理空值,还可以在这里进行数据缓存,包括后期的一些扩展都很方便
相关文章推荐
- Android核心基础-7.Android 网络通信-8.下载
- 网络流&二分图学习总结
- https
- HTTP协议基础解读
- Android 中在程序启动的时候自动检测网络状态(WiFi/手机网络)
- Android核心基础-7.Android 网络通信-7.上传
- 网络IO模型
- USACO 奶牛食品(网络流)
- JAVA网络编程之——URL类
- 转:HTTP长连接和短连接原理浅析
- C#网络编程《二》
- 理解SSL(https)中的对称加密与非对称加密
- Virtualbox之Ubuntu虚拟机网络访问设置
- 8月2日----TCP Socket 编程
- Windows Socket网络编程——第二章 Windows Socket概念
- Redis高可用开源缓存集群方案--总结自网络
- java基础第九讲——反射、工厂设计模式、注解、线程、网络与线程的结合
- 将HttpServletRequest中的参数反射至实体类
- TCP协议中的三次握手和四次挥手(图解)&&TCP/IP 七层网络模型
- ACM hdu5352 最小费用最大流 模板 网络流