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

一、前言

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


二、demo

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

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

package com.kroc.net;

import java.util.Map;

import android.content.Context;
import android.os.Message;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.kroc.app.MyApp;
import com.kroc.util.NetWorkUtil;

/**
 * @author 林楷鹏
 * @description 网络相关工具类
 * @create 2014-9-27下午5:15:43
 * 
 */
public class NetHelper {
	
	private static RequestQueue requestQueue;//volley请求队列
	
	private CommonHandler mHandler;
	private Context mContext;
	
	public NetHelper(Context context, CommonHandler mHandler) {
		this.mContext = context;
		this.mHandler = mHandler;
	}
	
	/**
	 * 获取volley请求队列
	 * @return
	 */
	public static RequestQueue getRequestQueue(){
		if(requestQueue == null){
			requestQueue = Volley.newRequestQueue(MyApp.getApp());
		}
		return requestQueue;
	}
	
	/**
	 * post方式请求数据
	 * @param url
	 * @param params
	 */
	public void postAsString(String url, final Map<String, String> params){
		if(!NetWorkUtil.checkNetWork(mContext)){
			mHandler.createExceptionMsg(new CNoNetWorkException());
			return;
		}
		StringRequest request = new StringRequest(Request.Method.POST, url, resListener, errorListener){
			protected Map<String,String> getParams() throws AuthFailureError {
				return params;
			};
		};
		getRequestQueue().add(request);
	}
	/**
	 * get方式请求数据
	 * @param url
	 */
	public void getAsString(String url){
		if(!NetWorkUtil.checkNetWork(mContext)){
			mHandler.createExceptionMsg(new CNoNetWorkException());
			return;
		}
		StringRequest request = new StringRequest(Request.Method.GET, url, resListener, errorListener);
		getRequestQueue().add(request);
	}
	
	/**
	 * 响应回调
	 */
	private Listener<String> resListener = new Listener<String>() {

		@Override
		public void onResponse(String response) {
			Message msg = mHandler.obtainMessage();
			msg.obj = response;
			mHandler.handleMessage(msg);
		}
	};
	/**
	 * 错误回调
	 */
	private ErrorListener errorListener = new ErrorListener() {

		@Override
		public void onErrorResponse(VolleyError error) {
			if(error instanceof TimeoutError){
				mHandler.createExceptionMsg(new CTimeOutException());
			}
		}
	};
	
}
结合部分注释我相信还是可以看懂的,主要解释下几个重点:

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

private Listener<String> resListener = new Listener<String>() {

		@Override
		public void onResponse(String response) {
			Message msg = mHandler.obtainMessage();
			msg.obj = response;
			mHandler.handleMessage(msg);
		}
	};
异常情况,就传入自己写的handler的子类CommonHandler处理,下面会有介绍该类:

/**
	 * 错误回调
	 */
	private ErrorListener errorListener = new ErrorListener() {

		@Override
		public void onErrorResponse(VolleyError error) {
			if(error instanceof TimeoutError){
				mHandler.createExceptionMsg(new CTimeOutException());
			}
		}
	};


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

package com.kroc.net;

import java.util.Map;

import android.os.Handler;
import android.os.Message;

import com.kroc.test.BaseActivity;

/**
 * @author 林楷鹏
 * @description 网络结果处理
 * @create 2014-9-28下午5:10:26
 * 
 */
public abstract class CommonHandler extends Handler {

	protected BaseActivity mActivity;
	protected ICallBack mCallBack;//结果回调
	protected NetHelper mNetHelper;
	
	public CommonHandler(BaseActivity activity) {
		this.mActivity = activity;
	}
	
	public NetHelper getNetHelper(){
		if(mNetHelper == null){
			mNetHelper = new NetHelper(mActivity, this);
		}
		return mNetHelper;
	}
	/**
	 * 非通用处理,交给各个请求地方自己处理
	 * @param msg
	 */
	public abstract void handleMainMessage(Message msg);
	/**
	 * 请求服务器(不带参数)
	 * @param url
	 * @param callBack
	 */
	public abstract void request(ICallBack callBack, String url);
	/**
	 * 请求服务器(带参数)
	 * @param url
	 * @param callBack
	 * @param params
	 */
	public abstract void request(ICallBack callBack, String url, Map<String, String> params);
	
	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case NetValue.STATUS_NO_NETWORK:
		case NetValue.STATUS_TIMEOUT:
		case NetValue.STATUS_UNKNOWN:
			showToast(msg.obj.toString());
			break;
		default:
			handleMainMessage(msg);
			break;
		}
	}
	
	/**
	 * 处理通用异常,将异常封装成message分发出去,如超时、网络异常等
	 * @param exc
	 */
	public void createExceptionMsg(Exception exc){
		
		Message msg = this.obtainMessage();
		
		if(exc instanceof CNoNetWorkException){
			msg.what = NetValue.STATUS_NO_NETWORK;
			msg.obj = NetValue.TIP_NO_NETWORK;
		}else if(exc instanceof CTimeOutException){
			msg.what = NetValue.STATUS_TIMEOUT;
			msg.obj = NetValue.TIP_TIMEOUT;
		}else{
			msg.what = NetValue.STATUS_UNKNOWN;
			msg.obj = NetValue.TIP_UNKNOWN;
		}
		
		sendMessage(msg);
	}
	
	private void showToast(String content){
		//TODO 自己实现个toast显示
		System.out.println(content);
	}
}

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

/**
	 * 处理通用异常,将异常封装成message分发出去,如超时、网络异常等
	 * @param exc
	 */
	public void createExceptionMsg(Exception exc){
		
		Message msg = this.obtainMessage();
		
		if(exc instanceof CNoNetWorkException){
			msg.what = NetValue.STATUS_NO_NETWORK;
			msg.obj = NetValue.TIP_NO_NETWORK;
		}else if(exc instanceof CTimeOutException){
			msg.what = NetValue.STATUS_TIMEOUT;
			msg.obj = NetValue.TIP_TIMEOUT;
		}else{
			msg.what = NetValue.STATUS_UNKNOWN;
			msg.obj = NetValue.TIP_UNKNOWN;
		}
		
		sendMessage(msg);
	}
在此方法当中将异常装到message当中,然后send出去,再复写handleMessage(Message msg)进行处理,如下:

@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case NetValue.STATUS_NO_NETWORK:
		case NetValue.STATUS_TIMEOUT:
		case NetValue.STATUS_UNKNOWN:
			showToast(msg.obj.toString());
			break;
		default:
			handleMainMessage(msg);
			break;
		}
	}
这里就可以将通用的异常解决掉了,剩下的就是正确的结果,交给handleMainMessage(Message msg),而你可以发现,这个方法我把它定义成抽象方法,为何?就要子类自己去实现处理,这就是模板设计模式的一个好处。


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

package com.kroc.test;

import java.util.Map;

import android.os.Message;

import com.kroc.net.CommonHandler;
import com.kroc.net.ICallBack;

public class TestBusiness extends CommonHandler {
	
	public TestBusiness(BaseActivity activity) {
		super(activity);
	}

	@Override
	public void handleMainMessage(Message msg) {
		mCallBack.displayResult(ICallBack.SUCCESS, msg.obj.toString());
	}

	@Override
	public void request(ICallBack callBack, String url) {
		this.mCallBack = callBack;
		getNetHelper().getAsString(url);
	}

	@Override
	public void request(ICallBack callBack, String url,
			Map<String, String> params) {

	}

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

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

package com.kroc.test;

import com.kroc.net.ICallBack;
import com.kroc.net.NetValue;

import android.os.Bundle;

public class TestActivity extends BaseActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//请求数据
		TestBusiness business = new TestBusiness(this);
		business.request(new ICallBack() {
			
			@Override
			public void displayResult(int status, Object... params) {
				//处理结果
				System.out.println("结果这里:"+params[0]);
				
			}
		}, NetValue.TEST_URL);
	}
}


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

正常情况如下:



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



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


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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值