转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)
http://blog.csdn.net/kroclin/article/details/40540761
一、前言
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网络,结果如下:
好啦,大概就是这样,不好的还希望批判哈哈~别太粗鲁哦。
版权声明:本文为博主原创文章,未经博主允许不得转载。
转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)的更多相关文章
- android基于开源网络框架asychhttpclient,二次封装为通用网络请求组件
网络请求是全部App都不可缺少的功能,假设每次开发都重写一次网络请求或者将曾经的代码拷贝到新的App中,不是非常合理,出于此目的,我希望将整个网络请求框架独立出来,与业务逻辑分隔开,这样就能够避免每次 ...
- Flutter用dio封装http网络请求,设置统一的请求地址、headers及处理返回内容
封装http请求是项目中经常需要做的,常用于设置通用请求地址.请求headers以及处理返回结果,例如在项目中开发地址.测试地址.上线地址是不一样的,当在封装的请求设置好默认地址之后只需要改一个地址而 ...
- 基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类
这段时间做新的Android项目的client和和REST API通讯框架架构设计.使用了非常多新技术,终于的方案也相当简洁优雅.client仅仅须要传Java对象,server端返回json字符串, ...
- vue+axois 封装请求+拦截器(请求锁+统一错误)
需求 封装常用请求 拦截器-请求锁 统一处理错误码 一.封装常用的请求 解决痛点:不要每一个模块的api都还要写get,post,patch请求方法.直接将这些常用的方法封装好. 解决方案:写一个类 ...
- Java基础知识强化之网络编程笔记24:Android网络通信之 AndroidAsync(基于nio的异步通信库)
1. AndroidAsync AndroidAsync 是一个基于nio的异步socket ,http(客户端服务器端),websocket,socket.io库,AndroidAsync 是一 ...
- Java基础知识强化之网络编程笔记23:Android网络通信之 Volley(Google开源网络通信库)
联合网上资料学习:http://www.open-open.com/lib/view/open1451223702339.html 一.Volley的介绍 1. Volley简介 在这之前,我们在程序 ...
- 基于 fetch 的请求封装
原生 fetch 请求失败后(如无网络)状态会变成 reject 走 .catch .绝大多数情况下业务场景只需要给个 toast 等简单处理.每个请求都 .catch 会显得格外繁琐,并且如果不 . ...
- 安卓中自定义并使用Volley框架请求网络
大家好,今天我们讲一下如何使用Volley框架请求网络,为何要使用Volley框架,这就要先说一下使用Volley框架请求网络的优点了,volley是易于定制的,即你可以根据需求来设定volley框架 ...
- Volley网络请求框架的基本用法
备注: 本笔记是参照了 http://blog.csdn.net/ysh06201418/article/details/46443235 学习之后写下的 简介: Volley是google官网退 ...
随机推荐
- centos启动流程[转]
启动流程概览 在硬件驱动成功后,Kernel 会主动呼叫 init 程序,而 init 会取得 run-level 资讯: init 运行 /etc/rc.d/rc.sysinit 文件来准备软件运行 ...
- matlab 工具之各种降维方法工具包,下载及使用教程,有PCA, LDA, 等等。。。
最近跑深度学习,提出的feature是4096维的,放到我们的程序里,跑得很慢,很慢.... 于是,一怒之下,就给他降维处理了,但是matlab 自带的什么pca( ), princomp( )函数, ...
- IL-rewriting profiler
https://blogs.msdn.microsoft.com/davbr/2007/03/06/creating-an-il-rewriting-profiler/ https://blogs.m ...
- Caffe-windows上训练自己的数据
1.数据获取 在网上选择特定类别,下载相应的若干张图片.可以网页另存或者图片下载器.本例中保存了小狗.菊花.梅花三类各两百多张. 2.重命名 import os import os.path root ...
- linux如何查看磁盘剩余空间
[root@Linux var]# df -hl 文件系统 容量 已用 可用 已用% 挂载点 /dev/hdb2 75G 75G 0 100% / /dev/hdb1 99M 9.2M 85M 10% ...
- Python学习笔记——文件
1.文件只是连续的字节序列 open()内建函数是打开文件之门的钥匙 file_obj=open(file_name,access_mode='r/w/a,' buffering=-1) file_n ...
- 如何将maven项目导入myeclipse中
在mvn的项目中 pom.xml 文件所在目录, 运行 mvn eclipse:clean eclipse:eclipse ,会自动将mvn工程转成eclipse工程, 然后在eclipse中 &qu ...
- 【转】keypress keydown keyup 区别
KeyPress主要用来接收字母.数字等ANSI字符,而 KeyDown 和 KeyUP 事件过程可以处理任何不被 KeyPress 识别的击键,诸如:功能键(F1-F12).编辑键.定位键以及任何这 ...
- redis配置文件解析
Redis是一个简单高效的内存KV数据库,基本上下载源码make install,编译完成,然后进入src目录运行redis-server即可运行.就是因为这么简单往往有朋友直接运行,将没有密码的re ...
- Phonegap在ios7上系统状态栏的问题解决
用Phonegap+jqm开发的应用,在ios6下没问题,但是在ios7下会出现如下系统状态栏和header重合的问题,搜索了一下,发现这其实是 phonegap当前版本的一个已知问题,通过修改./p ...