转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)

http://blog.csdn.net/kroclin/article/details/40540761

一、前言

volley的发布让网络请求也变得十分便利,但是我们通常懒得很想用一两句代码实现一个网络请求,其实你再经过封装就可以做到的。还有就是实际开发当中,我们会常常遇到很多异常情况,如网络异常、超时异常等等,那么我们如果有10个activity需要请求数据,那么在10个activity当中都去处理这些异常就变得十分麻烦,通过合理的设计其实我们能够在一个地方对异常情况进行统一处理,只有正确情况,才把数据返回给activity进行展示。这里我要介绍的就是这种方法,实际开发当中,合理的设计一些代码是很重要的,可以让你的开发变得更加简便、快捷。就像一样的食料,交给一个厨师和一个不会做饭的人,做出来的显然是不同的。

二、demo

喜欢通过实际demo来阐述一个解决问题的办法。上代码

1、首先是对volley进行再封装,这里只是简单的用了几个方法而已,volley还有很多强大的地方等待你去发现,我算抛砖引玉吧~~

[java] view plaincopy

  1. package com.kroc.net;
  2. import java.util.Map;
  3. import android.content.Context;
  4. import android.os.Message;
  5. import com.android.volley.AuthFailureError;
  6. import com.android.volley.Request;
  7. import com.android.volley.RequestQueue;
  8. import com.android.volley.Response.ErrorListener;
  9. import com.android.volley.Response.Listener;
  10. import com.android.volley.TimeoutError;
  11. import com.android.volley.VolleyError;
  12. import com.android.volley.toolbox.StringRequest;
  13. import com.android.volley.toolbox.Volley;
  14. import com.kroc.app.MyApp;
  15. import com.kroc.util.NetWorkUtil;
  16. /**
  17. * @author 林楷鹏
  18. * @description 网络相关工具类
  19. * @create 2014-9-27下午5:15:43
  20. *
  21. */
  22. public class NetHelper {
  23. private static RequestQueue requestQueue;//volley请求队列
  24. private CommonHandler mHandler;
  25. private Context mContext;
  26. public NetHelper(Context context, CommonHandler mHandler) {
  27. this.mContext = context;
  28. this.mHandler = mHandler;
  29. }
  30. /**
  31. * 获取volley请求队列
  32. * @return
  33. */
  34. public static RequestQueue getRequestQueue(){
  35. if(requestQueue == null){
  36. requestQueue = Volley.newRequestQueue(MyApp.getApp());
  37. }
  38. return requestQueue;
  39. }
  40. /**
  41. * post方式请求数据
  42. * @param url
  43. * @param params
  44. */
  45. public void postAsString(String url, final Map<String, String> params){
  46. if(!NetWorkUtil.checkNetWork(mContext)){
  47. mHandler.createExceptionMsg(new CNoNetWorkException());
  48. return;
  49. }
  50. StringRequest request = new StringRequest(Request.Method.POST, url, resListener, errorListener){
  51. protected Map<String,String> getParams() throws AuthFailureError {
  52. return params;
  53. };
  54. };
  55. getRequestQueue().add(request);
  56. }
  57. /**
  58. * get方式请求数据
  59. * @param url
  60. */
  61. public void getAsString(String url){
  62. if(!NetWorkUtil.checkNetWork(mContext)){
  63. mHandler.createExceptionMsg(new CNoNetWorkException());
  64. return;
  65. }
  66. StringRequest request = new StringRequest(Request.Method.GET, url, resListener, errorListener);
  67. getRequestQueue().add(request);
  68. }
  69. /**
  70. * 响应回调
  71. */
  72. private Listener<String> resListener = new Listener<String>() {
  73. @Override
  74. public void onResponse(String response) {
  75. Message msg = mHandler.obtainMessage();
  76. msg.obj = response;
  77. mHandler.handleMessage(msg);
  78. }
  79. };
  80. /**
  81. * 错误回调
  82. */
  83. private ErrorListener errorListener = new ErrorListener() {
  84. @Override
  85. public void onErrorResponse(VolleyError error) {
  86. if(error instanceof TimeoutError){
  87. mHandler.createExceptionMsg(new CTimeOutException());
  88. }
  89. }
  90. };
  91. }

结合部分注释我相信还是可以看懂的,主要解释下几个重点:

正确响应了,通过handler进行分发响应结果:

[java] view plaincopy

  1. private Listener<String> resListener = new Listener<String>() {
  2. @Override
  3. public void onResponse(String response) {
  4. Message msg = mHandler.obtainMessage();
  5. msg.obj = response;
  6. mHandler.handleMessage(msg);
  7. }
  8. };

异常情况,就传入自己写的handler的子类CommonHandler处理,下面会有介绍该类:

[java] view plaincopy

  1. /**
  2. * 错误回调
  3. */
  4. private ErrorListener errorListener = new ErrorListener() {
  5. @Override
  6. public void onErrorResponse(VolleyError error) {
  7. if(error instanceof TimeoutError){
  8. mHandler.createExceptionMsg(new CTimeOutException());
  9. }
  10. }
  11. };

2、继承handler的CommonHandler,写成抽象类就是一种设计,设计模式当中叫做模板设计模式,如果不了解,可以看我的另外文章有介绍:《设计模式学习(一)—— 模板设计模式》。

[java] view plaincopy

  1. package com.kroc.net;
  2. import java.util.Map;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import com.kroc.test.BaseActivity;
  6. /**
  7. * @author 林楷鹏
  8. * @description 网络结果处理
  9. * @create 2014-9-28下午5:10:26
  10. *
  11. */
  12. public abstract class CommonHandler extends Handler {
  13. protected BaseActivity mActivity;
  14. protected ICallBack mCallBack;//结果回调
  15. protected NetHelper mNetHelper;
  16. public CommonHandler(BaseActivity activity) {
  17. this.mActivity = activity;
  18. }
  19. public NetHelper getNetHelper(){
  20. if(mNetHelper == null){
  21. mNetHelper = new NetHelper(mActivity, this);
  22. }
  23. return mNetHelper;
  24. }
  25. /**
  26. * 非通用处理,交给各个请求地方自己处理
  27. * @param msg
  28. */
  29. public abstract void handleMainMessage(Message msg);
  30. /**
  31. * 请求服务器(不带参数)
  32. * @param url
  33. * @param callBack
  34. */
  35. public abstract void request(ICallBack callBack, String url);
  36. /**
  37. * 请求服务器(带参数)
  38. * @param url
  39. * @param callBack
  40. * @param params
  41. */
  42. public abstract void request(ICallBack callBack, String url, Map<String, String> params);
  43. @Override
  44. public void handleMessage(Message msg) {
  45. switch (msg.what) {
  46. case NetValue.STATUS_NO_NETWORK:
  47. case NetValue.STATUS_TIMEOUT:
  48. case NetValue.STATUS_UNKNOWN:
  49. showToast(msg.obj.toString());
  50. break;
  51. default:
  52. handleMainMessage(msg);
  53. break;
  54. }
  55. }
  56. /**
  57. * 处理通用异常,将异常封装成message分发出去,如超时、网络异常等
  58. * @param exc
  59. */
  60. public void createExceptionMsg(Exception exc){
  61. Message msg = this.obtainMessage();
  62. if(exc instanceof CNoNetWorkException){
  63. msg.what = NetValue.STATUS_NO_NETWORK;
  64. msg.obj = NetValue.TIP_NO_NETWORK;
  65. }else if(exc instanceof CTimeOutException){
  66. msg.what = NetValue.STATUS_TIMEOUT;
  67. msg.obj = NetValue.TIP_TIMEOUT;
  68. }else{
  69. msg.what = NetValue.STATUS_UNKNOWN;
  70. msg.obj = NetValue.TIP_UNKNOWN;
  71. }
  72. sendMessage(msg);
  73. }
  74. private void showToast(String content){
  75. //TODO 自己实现个toast显示
  76. System.out.println(content);
  77. }
  78. }

类中主要的点就在对异常数据的处理,如下:

[java] view plaincopy

  1. /**
  2. * 处理通用异常,将异常封装成message分发出去,如超时、网络异常等
  3. * @param exc
  4. */
  5. public void createExceptionMsg(Exception exc){
  6. Message msg = this.obtainMessage();
  7. if(exc instanceof CNoNetWorkException){
  8. msg.what = NetValue.STATUS_NO_NETWORK;
  9. msg.obj = NetValue.TIP_NO_NETWORK;
  10. }else if(exc instanceof CTimeOutException){
  11. msg.what = NetValue.STATUS_TIMEOUT;
  12. msg.obj = NetValue.TIP_TIMEOUT;
  13. }else{
  14. msg.what = NetValue.STATUS_UNKNOWN;
  15. msg.obj = NetValue.TIP_UNKNOWN;
  16. }
  17. sendMessage(msg);
  18. }

在此方法当中将异常装到message当中,然后send出去,再复写handleMessage(Message msg)进行处理,如下:

[java] view plaincopy

  1. @Override
  2. public void handleMessage(Message msg) {
  3. switch (msg.what) {
  4. case NetValue.STATUS_NO_NETWORK:
  5. case NetValue.STATUS_TIMEOUT:
  6. case NetValue.STATUS_UNKNOWN:
  7. showToast(msg.obj.toString());
  8. break;
  9. default:
  10. handleMainMessage(msg);
  11. break;
  12. }
  13. }

这里就可以将通用的异常解决掉了,剩下的就是正确的结果,交给handleMainMessage(Message msg),而你可以发现,这个方法我把它定义成抽象方法,为何?就要子类自己去实现处理,这就是模板设计模式的一个好处。

3、好啦,比较重点的两个类也在此。折腾了这么一会,上些测试代码看看怎样~~此类继承了刚刚的抽象类CommonHandler,实现抽象方法:

[java] view plaincopy

  1. package com.kroc.test;
  2. import java.util.Map;
  3. import android.os.Message;
  4. import com.kroc.net.CommonHandler;
  5. import com.kroc.net.ICallBack;
  6. public class TestBusiness extends CommonHandler {
  7. public TestBusiness(BaseActivity activity) {
  8. super(activity);
  9. }
  10. @Override
  11. public void handleMainMessage(Message msg) {
  12. mCallBack.displayResult(ICallBack.SUCCESS, msg.obj.toString());
  13. }
  14. @Override
  15. public void request(ICallBack callBack, String url) {
  16. this.mCallBack = callBack;
  17. getNetHelper().getAsString(url);
  18. }
  19. @Override
  20. public void request(ICallBack callBack, String url,
  21. Map<String, String> params) {
  22. }
  23. }

这里为了方便测试,我用get请求,准备请求个百度网页哈哈~此类我通常叫做xx的业务处理层,由于demo简陋,就没太多东西,实际当中就在这里处理数据,解析json、存储到文件、数据库啊等等等等......

最后在activity中发起请求,拿到结果,就几行,真的。

[java] view plaincopy

  1. package com.kroc.test;
  2. import com.kroc.net.ICallBack;
  3. import com.kroc.net.NetValue;
  4. import android.os.Bundle;
  5. public class TestActivity extends BaseActivity {
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. //请求数据
  10. TestBusiness business = new TestBusiness(this);
  11. business.request(new ICallBack() {
  12. @Override
  13. public void displayResult(int status, Object... params) {
  14. //处理结果
  15. System.out.println("结果这里:"+params[0]);
  16. }
  17. }, NetValue.TEST_URL);
  18. }
  19. }

我们看看打印结果,为了展示方便就这样简陋点啦,不要在意这些细节哈哈~~

正常情况如下:

然后,试下异常,关掉手机WiFi、还有3G网络,结果如下:

好啦,大概就是这样,不好的还希望批判哈哈~别太粗鲁哦。

~~~~代码下载~~~~

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-21 14:35:52

转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)的相关文章

android基于开源网络框架asychhttpclient,二次封装为通用网络请求组件

网络请求是全部App都不可缺少的功能,假设每次开发都重写一次网络请求或者将曾经的代码拷贝到新的App中,不是非常合理,出于此目的,我希望将整个网络请求框架独立出来,与业务逻辑分隔开,这样就能够避免每次都要又一次编写网络请求,于是基于我比較熟悉的asynchttpclient又一次二次封装了一个网络请求框架. 思路:网络请求层唯一的功能就是发送请求,接收响应数据,请求取消,cookie处理这几个功能,二次助封装后这些功能能够直接调用封装好的方法就可以. 二次助封装代码例如以下: 1.功能接口: /

基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类

这段时间做新的Android项目的客户端和和REST API通讯框架架构设计,使用了很多新技术,最终的方案也相当简洁优雅,客户端只需要传Java对象,服务器端返回json字符串,自动解析成Java对象, 无状态安全验证基于JWT实现,JWT规范的细节可以参考我前面的文章.JWT的token和数据防篡改签名统一放在HTTP Header中,这样就实现了对请求内容和返回结果的无侵入性,服务器端也可以在全局过滤器中统一处理安全验证. Android客户端使用了Volley网络请求框架和Gson解析库,

捕获异常、存sd卡、封装请求头体、加密map值、网络工具类、生成Json、Https协议、传log日志到服务器、app崩溃友好重启

点击打开链接,免积分下载 在集成了统计SDK(友盟统计,百度统计等)之后,有一个非常有利于测试的功能:错误分析!此功能能够将程序在运行中碰到的崩溃(runtimeException)问题反馈到服务器,帮助开发者改善产品,多适配机器.然而在公司android开发中不集成这些SDK,那应该怎么实现这样的功能呢?下面让我们来看下如何使用UncaughtExceptionHandler来捕获异常. 在Android开发中,常常会出现uncheched Exception 导致程序的crash,为了提供良

Java基础知识强化之网络编程笔记24:Android网络通信之 AndroidAsync(基于nio的异步通信库)

1. AndroidAsync   AndroidAsync 是一个基于nio的异步socket ,http(客户端服务器端),websocket,socket.io库,AndroidAsync 是一个底层的网络协议库,如果你想要一个容易使用,高级的,http请求库,请使用Ion(它是基于AndroidAsync 的),正常来说开发者更倾向于使用  Ion. 如果你需要一个未被封装的Android的raw Socket, HTTP client/server, WebSocket, and So

Android开发之网络请求通信专题(一):基于HttpURLConnection的请求通信

在Android开发中,网络请求必然是必不可少.一般而言,都是基于http的网络请求.有时候也会有SOCKET请求,这个后续的专题再讲.今天,我们就先讲讲常用的Http请求. http求情自然是遵循http协议的,相关内容请转接:Java学习笔记之Http协议详解 好了,开始今天的正题. 一.基础HTTPURL请求方式 我们先来看一个最简单的例子,通过get方法请求拿到返回值 1.用get方式请求 URL url = new URL( "http://192.168.31.144:10010/M

安卓中自定义并使用Volley框架请求网络

大家好,今天我们讲一下如何使用Volley框架请求网络,为何要使用Volley框架,这就要先说一下使用Volley框架请求网络的优点了,volley是易于定制的,即你可以根据需求来设定volley框架,还有volley框架支持请求的优先级设定,即你可以自主设定网络请求的优先级,还有就是volley框架请求支持取消单个或多个请求,这个一会设置请求的时候会特别说明,还有它可以自动调度网络请求,至于其他的如代码的健壮性.支持多并发等等就不一一列举了,说了那么多下面就介绍如何自定义并使用Volley框架

Volley网络请求框架简析——Android网络请求框架(三)

题记-- 人来到这个世界上,只有两件事情,生与死, 一件事完了,另一件事还急什么? 有缘而来,无缘而去, 识自本心,见自本性 不起妄缘,无心无为 自由自在,动静自如 冷暖自知,则是修行 1.初始化一个消息请求队列以及网络请求工具类对象 /** * Created by androidlongs on 16/7/1. * 网络请求访问框架 */ public class VollyRequestUtils { /** * Volley框架使用工具类对象 */ private static Voll

ios开发网络学习:一:NSURLConnection发送GET,POST请求

#import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> /** 注释 */ @property (nonatomic, strong) NSMutableData *resultData; @end @implementation ViewController #pragma mark ---------------------- #pragma mark la

网络编程(一) 利用NSURLSession发送GET POST请求

Xcode 7.0后,http链接不能直接访问(https可以),需要在Info.plist增加下面一项才能正确访问. 使用NSURLSession进行网络请求的流程: 1.构造NSURL 2.构造NSURLRequest请求对象 3.构造NSURLSession会话对象 4.创建网络请求任务:dataTask, downloadTask, uploadTask 5.发送网络请求 1.GET 请求(GET一般用于获取/查询资源信息) - (void)HTTPGET { //1.构造NSURL N