之前讲了ym—— Android网络框架Volley(体验篇),大家应该了解了volley的使用,接下来我们要看看如何把volley使用到实战项目里面,我们先考虑下一些问题:

从上一篇来看 mQueue 只需要一个对象即可,new RequestQueue对象对资源一种浪费,我们应该在application,以及可以把取消请求的方法也在application进行统一管理,看以下代码:

  1. package com.chronocloud.lib.base;
  2. import android.app.Application;
  3. import android.text.TextUtils;
  4. import com.android.volley.Request;
  5. import com.android.volley.RequestQueue;
  6. import com.android.volley.VolleyLog;
  7. import com.android.volley.toolbox.Volley;
  8. public class ApplicationController extends Application {
  9. /**
  10. * Log or request TAG
  11. */
  12. public static final String TAG = "VolleyPatterns";
  13. /**
  14. * Global request queue for Volley
  15. */
  16. private RequestQueue mRequestQueue;
  17. /**
  18. * A singleton instance of the application class for easy access in other
  19. * places
  20. */
  21. private static ApplicationController sInstance;
  22. @Override
  23. public void onCreate() {
  24. super.onCreate();
  25. // initialize the singleton
  26. sInstance = this;
  27. }
  28. /**
  29. * @return ApplicationController singleton instance
  30. */
  31. public static synchronized ApplicationController getInstance() {
  32. return sInstance;
  33. }
  34. /**
  35. * @return The Volley Request queue, the queue will be created if it is null
  36. */
  37. public RequestQueue getRequestQueue() {
  38. // lazy initialize the request queue, the queue instance will be
  39. // created when it is accessed for the first time
  40. if (mRequestQueue == null) {
  41. // 1
  42. // 2
  43. synchronized (ApplicationController.class) {
  44. if (mRequestQueue == null) {
  45. mRequestQueue = Volley
  46. .newRequestQueue(getApplicationContext());
  47. }
  48. }
  49. }
  50. return mRequestQueue;
  51. }
  52. /**
  53. * Adds the specified request to the global queue, if tag is specified then
  54. * it is used else Default TAG is used.
  55. *
  56. * @param req
  57. * @param tag
  58. */
  59. public <T> void addToRequestQueue(Request<T> req, String tag) {
  60. // set the default tag if tag is empty
  61. req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
  62. VolleyLog.d("Adding request to queue: %s", req.getUrl());
  63. getRequestQueue().add(req);
  64. }
  65. /**
  66. * Adds the specified request to the global queue using the Default TAG.
  67. *
  68. * @param req
  69. * @param tag
  70. */
  71. public <T> void addToRequestQueue(Request<T> req) {
  72. // set the default tag if tag is empty
  73. req.setTag(TAG);
  74. getRequestQueue().add(req);
  75. }
  76. /**
  77. * Cancels all pending requests by the specified TAG, it is important to
  78. * specify a TAG so that the pending/ongoing requests can be cancelled.
  79. *
  80. * @param tag
  81. */
  82. public void cancelPendingRequests(Object tag) {
  83. if (mRequestQueue != null) {
  84. mRequestQueue.cancelAll(tag);
  85. }
  86. }
  87. }

接下来就是Volley虽然给我们提供了很多不同的Request(JsonObjectRequest,JsonArrayRequest,StringRequest,ImageRequest),但是还是满足不了我们实战中的需求,我们实战开发中经常用到的是xml格式,Gson解析。

接下来我们来看看,如何自定义Request

XmlRequest:

  1. public class XMLRequest extends Request<XmlPullParser> {
  2. private final Listener<XmlPullParser> mListener;
  3. public XMLRequest(int method, String url, Listener<XmlPullParser> listener,
  4. ErrorListener errorListener) {
  5. super(method, url, errorListener);
  6. mListener = listener;
  7. }
  8. public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
  9. this(Method.GET, url, listener, errorListener);
  10. }
  11. @Override
  12. protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
  13. try {
  14. String xmlString = new String(response.data,
  15. HttpHeaderParser.parseCharset(response.headers));
  16. XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
  17. XmlPullParser xmlPullParser = factory.newPullParser();
  18. xmlPullParser.setInput(new StringReader(xmlString));
  19. return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
  20. } catch (UnsupportedEncodingException e) {
  21. return Response.error(new ParseError(e));
  22. } catch (XmlPullParserException e) {
  23. return Response.error(new ParseError(e));
  24. }
  25. }
  26. @Override
  27. protected void deliverResponse(XmlPullParser response) {
  28. mListener.onResponse(response);
  29. }
  30. }

GsonRequest(注意需要自行导入gson.jar):

  1. public class GsonRequest<T> extends Request<T> {
  2. private final Listener<T> mListener;
  3. private Gson mGson;
  4. private Class<T> mClass;
  5. public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener,
  6. ErrorListener errorListener) {
  7. super(method, url, errorListener);
  8. mGson = new Gson();
  9. mClass = clazz;
  10. mListener = listener;
  11. }
  12. public GsonRequest(String url, Class<T> clazz, Listener<T> listener,
  13. ErrorListener errorListener) {
  14. this(Method.GET, url, clazz, listener, errorListener);
  15. }
  16. @Override
  17. protected Response<T> parseNetworkResponse(NetworkResponse response) {
  18. try {
  19. String jsonString = new String(response.data,
  20. HttpHeaderParser.parseCharset(response.headers));
  21. return Response.success(mGson.fromJson(jsonString, mClass),
  22. HttpHeaderParser.parseCacheHeaders(response));
  23. } catch (UnsupportedEncodingException e) {
  24. return Response.error(new ParseError(e));
  25. }
  26. }
  27. @Override
  28. protected void deliverResponse(T response) {
  29. mListener.onResponse(response);
  30. }
  31. }

接下只差最后一步了就是封装它的错误处理,使用过volley的都知道,volley的监听错误提示都是NoConnectionError。。。等等,这类的错误提示,显然这不是我们想给用户呈现的错误提示,因为就算提示了用户也不明白什么意思,所以我们还要封装一下,能让用户看的更清楚的理解这些错误提示。ym—— Android网络框架Volley(体验篇)我们讲过每个请求都需要设置一个失败的监听:

  1. // 共用失败回调
  2. private class StrErrListener implements ErrorListener {
  3. @Override
  4. public void onErrorResponse(VolleyError arg0) {
  5. Toast.makeText(mContext,
  6. VolleyErrorHelper.getMessage(arg0, mContext),
  7. Toast.LENGTH_LONG).show();
  8. }
  9. }

以上代码有个VolleyError对象,我们可以从这个对象上下手:

  1. package com.example.volley;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import android.content.Context;
  5. import com.android.volley.AuthFailureError;
  6. import com.android.volley.NetworkError;
  7. import com.android.volley.NetworkResponse;
  8. import com.android.volley.NoConnectionError;
  9. import com.android.volley.ServerError;
  10. import com.android.volley.TimeoutError;
  11. import com.android.volley.VolleyError;
  12. import com.google.gson.Gson;
  13. import com.google.gson.reflect.TypeToken;
  14. //正如前面代码看到的,在创建一个请求时,需要添加一个错误监听onErrorResponse。如果请求发生异常,会返回一个VolleyError实例。
  15. //以下是Volley的异常列表:
  16. //AuthFailureError:如果在做一个HTTP的身份验证,可能会发生这个错误。
  17. //NetworkError:Socket关闭,服务器宕机,DNS错误都会产生这个错误。
  18. //NoConnectionError:和NetworkError类似,这个是客户端没有网络连接。
  19. //ParseError:在使用JsonObjectRequest或JsonArrayRequest时,如果接收到的JSON是畸形,会产生异常。
  20. //SERVERERROR:服务器的响应的一个错误,最有可能的4xx或5xx HTTP状态代码。
  21. //TimeoutError:Socket超时,服务器太忙或网络延迟会产生这个异常。默认情况下,Volley的超时时间为2.5秒。如果得到这个错误可以使用RetryPolicy。
  22. public class VolleyErrorHelper {
  23. /**
  24. * Returns appropriate message which is to be displayed to the user against
  25. * the specified error object.
  26. *
  27. * @param error
  28. * @param context
  29. * @return
  30. */
  31. public static String getMessage(Object error, Context context) {
  32. if (error instanceof TimeoutError) {
  33. return context.getResources().getString(
  34. R.string.generic_server_down);
  35. } else if (isServerProblem(error)) {
  36. return handleServerError(error, context);
  37. } else if (isNetworkProblem(error)) {
  38. return context.getResources().getString(R.string.no_internet);
  39. }
  40. return context.getResources().getString(R.string.generic_error);
  41. }
  42. /**
  43. * Determines whether the error is related to network
  44. *
  45. * @param error
  46. * @return
  47. */
  48. private static boolean isNetworkProblem(Object error) {
  49. return (error instanceof NetworkError)
  50. || (error instanceof NoConnectionError);
  51. }
  52. /**
  53. * Determines whether the error is related to server
  54. *
  55. * @param error
  56. * @return
  57. */
  58. private static boolean isServerProblem(Object error) {
  59. return (error instanceof ServerError)
  60. || (error instanceof AuthFailureError);
  61. }
  62. /**
  63. * Handles the server error, tries to determine whether to show a stock
  64. * message or to show a message retrieved from the server.
  65. *
  66. * @param err
  67. * @param context
  68. * @return
  69. */
  70. private static String handleServerError(Object err, Context context) {
  71. VolleyError error = (VolleyError) err;
  72. NetworkResponse response = error.networkResponse;
  73. if (response != null) {
  74. switch (response.statusCode) {
  75. case 404:
  76. case 422:
  77. case 401:
  78. try {
  79. // server might return error like this { "error":
  80. // "Some error occured" }
  81. // Use "Gson" to parse the result
  82. HashMap<String, String> result = new Gson().fromJson(
  83. new String(response.data),
  84. new TypeToken<Map<String, String>>() {
  85. }.getType());
  86. if (result != null && result.containsKey("error")) {
  87. return result.get("error");
  88. }
  89. } catch (Exception e) {
  90. e.printStackTrace();
  91. }
  92. // invalid request
  93. return error.getMessage();
  94. default:
  95. return context.getResources().getString(
  96. R.string.generic_server_down);
  97. }
  98. }
  99. return context.getResources().getString(R.string.generic_error);
  100. }
  101. }

以上代码中引用的xml是:

  1. <string name="no_internet">无网络连接~!</string>
  2. <string name="generic_server_down">连接服务器失败~!</string>
  3. <string name="generic_error">网络异常,请稍后再试~!</string>

接下来,数据请求这一块已经说完了,我们来说下图片这一块,我个人喜欢使用universal-image-loader而不是volley自己提供的(个人认为使用起来universal-image-loader更便捷一些)。好啦讲完了,大家可以去实战开发了~!不懂或者遇到问题的可以留言讨论~!

Android网络框架Volley(实战篇)的更多相关文章

  1. Android网络框架Volley(体验篇)

    Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...

  2. ym—— Android网络框架Volley(终极篇)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103).谢谢支持! 没看使用过Volley的同学能够,先看看Android网络框架Volley(体验篇)和 ...

  3. ym—— Android网络框架Volley(体验篇)

    VolleyGoogle I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...

  4. Android网络框架Volley

    Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...

  5. Google官方网络框架Volley实战——QQ吉凶测试,南无阿弥陀佛!

    Google官方网络框架Volley实战--QQ吉凶测试,南无阿弥陀佛! 这次我们用第三方的接口来做一个QQ吉凶的测试项目,代码依然是比较的简单 无图无真相 直接撸代码了,详细解释都已经写在注释里了 ...

  6. Android网络框架-Volley实践 使用Volley打造自己定义ListView

    这篇文章翻译自Ravi Tamada博客中的Android Custom ListView with Image and Text using Volley 终于效果 这个ListView呈现了一些影 ...

  7. Android 网络框架Volley的使用

    Volley简介 在平时的开发过程中,我们的应用几乎总是在和网络打交道, 在android下的网络编程一般都是基于Http协议的 ,常见的是HttpURLConnection和HttpClient 两 ...

  8. Android 网络框架 volley源码剖析

    转载请注明出处:  http://blog.csdn.net/guolin_blog/article/details/17656437 经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了, ...

  9. Android 网络框架---Volley

    /** * Volley 可以同时请求多个,允许高并发 * 特性: * 1.JSON.图片等的异步下载 * 2.网络请求的排序(Scheduling) * 3.网络请求的优先级处理 * 4.缓存 * ...

随机推荐

  1. Linux Apache SVN

    yum install mod_dav_svn subversion  httpd mkdir /var/www/svnsvnadmin create /var/www/svn/puppetcd /v ...

  2. javascript异步加载详解(转)

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...

  3. yieId浅谈

    例子:在不使用yieId时,通常我们都会采取先遍历再把元素加到新的List中 using (var reader = SqlHelper.ExecuteReader("")) { ...

  4. Tuning “enq:TX – row lock contention” events

    enq是一种保护共享资源的锁定机制,一个排队机制 排它机制从一个事务的第一次改变直到rollback or commit 结束这个事务, TX等待mode是6,当一个session 在一个表的行级锁定 ...

  5. 使用Reveal.app调试整个项目UI时间,增加LD指令 -Objc引起项目中多个静态库冲突问题

    今天接触到一个新的UI调试工具教程如下: iOS真机UI调试利器——Reveal 引入增加-ObjC -framework Reveal指令后,发现项目出现多重静态库冲突问题, 首先介绍一个指令: - ...

  6. c语言中文件相关操作

    一 .首先介绍一下数据文件的类型: 1.二进制文件(映像文件):在内存中以二进制形式存取. 2.文本文件(ascii文件):以ascii码形式存取的文件. 通俗的讲,在Mac下,你把一个文件丢进记事本 ...

  7. 中文翻译:pjsip文档(四)之ICE Session的使用方法

    1:pjsip教程(一)之PJNATH简介 2:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介 3:pjsip教程(三)之ICE ...

  8. 8种CSS清除浮动的方法优缺点分析

    为什么清除CSS浮动这么难? 因为浮动会使当前标签产生向上浮的效果,同时会影响到前后标签.父级标签的位置及 width height 属性.而且同样的代码,在各种浏览器中显示效果也有可能不相同,这样让 ...

  9. Windows phone 之手势识别(Drag)

    首先,在XAML页面中,添加如下代码: 前提,别忘了添加 1.引入dll (silverlight for wndows phone toolkit) 2.引入命名空间 xmlns:toolkit=& ...

  10. Javascript 中 call 的两种用法

    用法一(常见用法): 表现形式为:一个对象.方法.call(另一个对象),意义是用另一个对象代替当前对象,执行当前对象的方法.先看示例: function Class1(){ this.name = ...