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

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

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

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

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

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



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

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


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

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

    在此方法当中将异常装到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.   
    3. import java.util.Map;  
    4.   
    5. import android.os.Message;  
    6.   
    7. import com.kroc.net.CommonHandler;  
    8. import com.kroc.net.ICallBack;  
    9.   
    10. public class TestBusiness extends CommonHandler {  
    11.       
    12.     public TestBusiness(BaseActivity activity) {  
    13.         super(activity);  
    14.     }  
    15.   
    16.     @Override  
    17.     public void handleMainMessage(Message msg) {  
    18.         mCallBack.displayResult(ICallBack.SUCCESS, msg.obj.toString());  
    19.     }  
    20.   
    21.     @Override  
    22.     public void request(ICallBack callBack, String url) {  
    23.         this.mCallBack = callBack;  
    24.         getNetHelper().getAsString(url);  
    25.     }  
    26.   
    27.     @Override  
    28.     public void request(ICallBack callBack, String url,  
    29.             Map<String, String> params) {  
    30.   
    31.     }  
    32.   
    33. }  

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

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

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

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

    正常情况如下:



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

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

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

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

  • 相关阅读:
    docker初次实验
    一行代码的高阶函数
    ubuntu卸载opencv
    opencv中的数据结构
    微信小程序从0到上线(一)环境搭建
    短链接系统的研究
    西红柿种植经验的个人总结【家庭种植】
    关于微信小程序工具input无法输入的问题
    面向对象的六大原则
    JS API WebSocket
  • 原文地址:https://www.cnblogs.com/awkflf11/p/4609183.html
Copyright © 2020-2023  润新知