Android网络框架Volley(实战篇)
从上一篇来看 mQueue 只需要一个对象即可,new RequestQueue对象对资源一种浪费,我们应该在application,以及可以把取消请求的方法也在application进行统一管理,看以下代码:
- package com.chronocloud.lib.base;
- import android.app.Application;
- import android.text.TextUtils;
- import com.android.volley.Request;
- import com.android.volley.RequestQueue;
- import com.android.volley.VolleyLog;
- import com.android.volley.toolbox.Volley;
- public class ApplicationController extends Application {
- /**
- * Log or request TAG
- */
- public static final String TAG = "VolleyPatterns";
- /**
- * Global request queue for Volley
- */
- private RequestQueue mRequestQueue;
- /**
- * A singleton instance of the application class for easy access in other
- * places
- */
- private static ApplicationController sInstance;
- @Override
- public void onCreate() {
- super.onCreate();
- // initialize the singleton
- sInstance = this;
- }
- /**
- * @return ApplicationController singleton instance
- */
- public static synchronized ApplicationController getInstance() {
- return sInstance;
- }
- /**
- * @return The Volley Request queue, the queue will be created if it is null
- */
- public RequestQueue getRequestQueue() {
- // lazy initialize the request queue, the queue instance will be
- // created when it is accessed for the first time
- if (mRequestQueue == null) {
- // 1
- // 2
- synchronized (ApplicationController.class) {
- if (mRequestQueue == null) {
- mRequestQueue = Volley
- .newRequestQueue(getApplicationContext());
- }
- }
- }
- return mRequestQueue;
- }
- /**
- * Adds the specified request to the global queue, if tag is specified then
- * it is used else Default TAG is used.
- *
- * @param req
- * @param tag
- */
- public <T> void addToRequestQueue(Request<T> req, String tag) {
- // set the default tag if tag is empty
- req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
- VolleyLog.d("Adding request to queue: %s", req.getUrl());
- getRequestQueue().add(req);
- }
- /**
- * Adds the specified request to the global queue using the Default TAG.
- *
- * @param req
- * @param tag
- */
- public <T> void addToRequestQueue(Request<T> req) {
- // set the default tag if tag is empty
- req.setTag(TAG);
- getRequestQueue().add(req);
- }
- /**
- * Cancels all pending requests by the specified TAG, it is important to
- * specify a TAG so that the pending/ongoing requests can be cancelled.
- *
- * @param tag
- */
- public void cancelPendingRequests(Object tag) {
- if (mRequestQueue != null) {
- mRequestQueue.cancelAll(tag);
- }
- }
- }
接下来就是Volley虽然给我们提供了很多不同的Request(JsonObjectRequest,JsonArrayRequest,StringRequest,ImageRequest),但是还是满足不了我们实战中的需求,我们实战开发中经常用到的是xml格式,Gson解析。
接下来我们来看看,如何自定义Request
XmlRequest:
- public class XMLRequest extends Request<XmlPullParser> {
- private final Listener<XmlPullParser> mListener;
- public XMLRequest(int method, String url, Listener<XmlPullParser> listener,
- ErrorListener errorListener) {
- super(method, url, errorListener);
- mListener = listener;
- }
- public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
- this(Method.GET, url, listener, errorListener);
- }
- @Override
- protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
- try {
- String xmlString = new String(response.data,
- HttpHeaderParser.parseCharset(response.headers));
- XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
- XmlPullParser xmlPullParser = factory.newPullParser();
- xmlPullParser.setInput(new StringReader(xmlString));
- return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
- } catch (UnsupportedEncodingException e) {
- return Response.error(new ParseError(e));
- } catch (XmlPullParserException e) {
- return Response.error(new ParseError(e));
- }
- }
- @Override
- protected void deliverResponse(XmlPullParser response) {
- mListener.onResponse(response);
- }
- }
GsonRequest(注意需要自行导入gson.jar):
- public class GsonRequest<T> extends Request<T> {
- private final Listener<T> mListener;
- private Gson mGson;
- private Class<T> mClass;
- public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener,
- ErrorListener errorListener) {
- super(method, url, errorListener);
- mGson = new Gson();
- mClass = clazz;
- mListener = listener;
- }
- public GsonRequest(String url, Class<T> clazz, Listener<T> listener,
- ErrorListener errorListener) {
- this(Method.GET, url, clazz, listener, errorListener);
- }
- @Override
- protected Response<T> parseNetworkResponse(NetworkResponse response) {
- try {
- String jsonString = new String(response.data,
- HttpHeaderParser.parseCharset(response.headers));
- return Response.success(mGson.fromJson(jsonString, mClass),
- HttpHeaderParser.parseCacheHeaders(response));
- } catch (UnsupportedEncodingException e) {
- return Response.error(new ParseError(e));
- }
- }
- @Override
- protected void deliverResponse(T response) {
- mListener.onResponse(response);
- }
- }
接下只差最后一步了就是封装它的错误处理,使用过volley的都知道,volley的监听错误提示都是NoConnectionError。。。等等,这类的错误提示,显然这不是我们想给用户呈现的错误提示,因为就算提示了用户也不明白什么意思,所以我们还要封装一下,能让用户看的更清楚的理解这些错误提示。ym—— Android网络框架Volley(体验篇)我们讲过每个请求都需要设置一个失败的监听:
- // 共用失败回调
- private class StrErrListener implements ErrorListener {
- @Override
- public void onErrorResponse(VolleyError arg0) {
- Toast.makeText(mContext,
- VolleyErrorHelper.getMessage(arg0, mContext),
- Toast.LENGTH_LONG).show();
- }
- }
以上代码有个VolleyError对象,我们可以从这个对象上下手:
- package com.example.volley;
- import java.util.HashMap;
- import java.util.Map;
- import android.content.Context;
- import com.android.volley.AuthFailureError;
- import com.android.volley.NetworkError;
- import com.android.volley.NetworkResponse;
- import com.android.volley.NoConnectionError;
- import com.android.volley.ServerError;
- import com.android.volley.TimeoutError;
- import com.android.volley.VolleyError;
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
- //正如前面代码看到的,在创建一个请求时,需要添加一个错误监听onErrorResponse。如果请求发生异常,会返回一个VolleyError实例。
- //以下是Volley的异常列表:
- //AuthFailureError:如果在做一个HTTP的身份验证,可能会发生这个错误。
- //NetworkError:Socket关闭,服务器宕机,DNS错误都会产生这个错误。
- //NoConnectionError:和NetworkError类似,这个是客户端没有网络连接。
- //ParseError:在使用JsonObjectRequest或JsonArrayRequest时,如果接收到的JSON是畸形,会产生异常。
- //SERVERERROR:服务器的响应的一个错误,最有可能的4xx或5xx HTTP状态代码。
- //TimeoutError:Socket超时,服务器太忙或网络延迟会产生这个异常。默认情况下,Volley的超时时间为2.5秒。如果得到这个错误可以使用RetryPolicy。
- public class VolleyErrorHelper {
- /**
- * Returns appropriate message which is to be displayed to the user against
- * the specified error object.
- *
- * @param error
- * @param context
- * @return
- */
- public static String getMessage(Object error, Context context) {
- if (error instanceof TimeoutError) {
- return context.getResources().getString(
- R.string.generic_server_down);
- } else if (isServerProblem(error)) {
- return handleServerError(error, context);
- } else if (isNetworkProblem(error)) {
- return context.getResources().getString(R.string.no_internet);
- }
- return context.getResources().getString(R.string.generic_error);
- }
- /**
- * Determines whether the error is related to network
- *
- * @param error
- * @return
- */
- private static boolean isNetworkProblem(Object error) {
- return (error instanceof NetworkError)
- || (error instanceof NoConnectionError);
- }
- /**
- * Determines whether the error is related to server
- *
- * @param error
- * @return
- */
- private static boolean isServerProblem(Object error) {
- return (error instanceof ServerError)
- || (error instanceof AuthFailureError);
- }
- /**
- * Handles the server error, tries to determine whether to show a stock
- * message or to show a message retrieved from the server.
- *
- * @param err
- * @param context
- * @return
- */
- private static String handleServerError(Object err, Context context) {
- VolleyError error = (VolleyError) err;
- NetworkResponse response = error.networkResponse;
- if (response != null) {
- switch (response.statusCode) {
- case 404:
- case 422:
- case 401:
- try {
- // server might return error like this { "error":
- // "Some error occured" }
- // Use "Gson" to parse the result
- HashMap<String, String> result = new Gson().fromJson(
- new String(response.data),
- new TypeToken<Map<String, String>>() {
- }.getType());
- if (result != null && result.containsKey("error")) {
- return result.get("error");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- // invalid request
- return error.getMessage();
- default:
- return context.getResources().getString(
- R.string.generic_server_down);
- }
- }
- return context.getResources().getString(R.string.generic_error);
- }
- }
以上代码中引用的xml是:
- <string name="no_internet">无网络连接~!</string>
- <string name="generic_server_down">连接服务器失败~!</string>
- <string name="generic_error">网络异常,请稍后再试~!</string>
接下来,数据请求这一块已经说完了,我们来说下图片这一块,我个人喜欢使用universal-image-loader而不是volley自己提供的(个人认为使用起来universal-image-loader更便捷一些)。好啦讲完了,大家可以去实战开发了~!不懂或者遇到问题的可以留言讨论~!
Android网络框架Volley(实战篇)的更多相关文章
- Android网络框架Volley(体验篇)
Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
- ym—— Android网络框架Volley(终极篇)
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103).谢谢支持! 没看使用过Volley的同学能够,先看看Android网络框架Volley(体验篇)和 ...
- ym—— Android网络框架Volley(体验篇)
VolleyGoogle I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
- Android网络框架Volley
Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
- Google官方网络框架Volley实战——QQ吉凶测试,南无阿弥陀佛!
Google官方网络框架Volley实战--QQ吉凶测试,南无阿弥陀佛! 这次我们用第三方的接口来做一个QQ吉凶的测试项目,代码依然是比较的简单 无图无真相 直接撸代码了,详细解释都已经写在注释里了 ...
- Android网络框架-Volley实践 使用Volley打造自己定义ListView
这篇文章翻译自Ravi Tamada博客中的Android Custom ListView with Image and Text using Volley 终于效果 这个ListView呈现了一些影 ...
- Android 网络框架Volley的使用
Volley简介 在平时的开发过程中,我们的应用几乎总是在和网络打交道, 在android下的网络编程一般都是基于Http协议的 ,常见的是HttpURLConnection和HttpClient 两 ...
- Android 网络框架 volley源码剖析
转载请注明出处: http://blog.csdn.net/guolin_blog/article/details/17656437 经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了, ...
- Android 网络框架---Volley
/** * Volley 可以同时请求多个,允许高并发 * 特性: * 1.JSON.图片等的异步下载 * 2.网络请求的排序(Scheduling) * 3.网络请求的优先级处理 * 4.缓存 * ...
随机推荐
- CentOS7安装vim7.4
卸载自带vim yum remove vim-enhanced vim-common 下载vim包 wget ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz ...
- C#入门教程(三)–接收用户输入、转义字符、类型转换-打造C#入门教程
上次教程主要讲解了visual stdio快捷键.变量相关的知识.具体教程戳这里:http://www.chengxiaoxiao.com/net/1027.html 越来越深入去写教程越来越发现,自 ...
- HDOJ-1754(简单线段树)
最近开始重新学习线段树,先从最简单的开始吧! I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 ...
- 解读zookeeper的配置项
zookeeper的默认配置文件为zookeeper/conf/zoo_sample.cfg,需要将其修改为zoo.cfg.其中各配置项的含义,解释如下: 1.tickTime:CS通信心跳数 Zoo ...
- ASP.NET Web API 通过参数控制返回类型(JSON|XML)
一个很实用的技巧,可以在访问web api服务的时候指定返回数据的格式类型,比如 json 或者 xml. 因为 web api 默认返回的是XML格式,但是现在json 比较流行,同时网上也有其他的 ...
- A题笔记(9)
No.2283 No.1387 vector<vector<char> > before, after; 可以创建一个容器的容器,注意 char 后的两个 “>” ,之间 ...
- winform中的chat
百度一下 源代码下载:百度一下
- highcharts时间图
这篇文章适合对highcharts已经有一定了解的猿友. 前两天想用highcharts做一个时间图,但是时间轴(x轴)的时间坐标并不是等间隔的,之前一直采用的方法是把时间做成等间隔的,然后没有数据的 ...
- HDU 1074 Doing Homework (dp+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...
- 一个由IsPrime算法引发的细节问题
//******************************* // // 2014年9月18日星期四,于宿舍撰写 // 作者:夏华林 // //******************* ...