Volley框架 以及 设置request超时时间
2015-05-12 11:54
204 查看
Volley提供了优美的框架,使android程序网络访问更容易、更快。
Volley抽象实现了底层的HTTP Client库,我们不需关注HTTP Client细节,专注于写出更加漂亮、干净的RESTful HTTP请求。
Volley请求会异步执行,不阻挡主线程。
一个优雅and稳健的请求队列
一个可扩展的架构,使开发者能实现自定义的请求和响应处理机制
能使用外部Http Client库
缓存策略
自定义的网络图像加载视图(NetworkImageView,ImageLoader等)
2、使用请求队列
3、异步的JSON、String请求
4、取消请求
5、重试失败的请求,自定义请求超时
6、设置请求头(HTTP headers)
7、使用Cookies
8、错误处理
Volley抽象实现了底层的HTTP Client库,我们不需关注HTTP Client细节,专注于写出更加漂亮、干净的RESTful HTTP请求。
Volley请求会异步执行,不阻挡主线程。
Volley提供的功能
封装了异步的RESTful请求API一个优雅and稳健的请求队列
一个可扩展的架构,使开发者能实现自定义的请求和响应处理机制
能使用外部Http Client库
缓存策略
自定义的网络图像加载视图(NetworkImageView,ImageLoader等)
为什么使用异步Http请求
Android中要求HTTP请求异步执行,如果在主线程执行HTTP请求,可能会抛出 android.os.NetworkOnMainThreadException 异常。阻塞主线程有一些严重的后果,它阻碍UI渲染,用户体验不流 畅,它可能会导致可怕的ANR(Application Not Responding)。要避免这些陷阱,作为一个开发者,应该始终确保HTTP请求是在一个不同的线程怎样使用Volley
1、安装和使用Volley库2、使用请求队列
3、异步的JSON、String请求
4、取消请求
5、重试失败的请求,自定义请求超时
6、设置请求头(HTTP headers)
7、使用Cookies
8、错误处理
1.安装和使用Volley库
引入Volley非常简单,首先,从git库先克隆一个下来:git clone https://android.googlesource.com/platform/frameworks/volley[/code] 然后编译为jar包,再把jar包放到自己的工程的libs目录。2.使用请求队列
Volley的所有请求都放在一个队列,然后进行处理,这里是你如何将创建一个请求队列:RequestQueue mRequestQueue = Volley.newRequestQueue(this); // 'this' is Context
理想的情况是把请求队列集中放到一个地方,最好是初始化应用程序类中初始化请求队列,下面类做到了这一点: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) { 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); } } }3.异步的JSON、String请求
Volley提供了以下的实用工具类进行异步HTTP请求:
JsonObjectRequest — To send and receive JSON Object from the Server
JsonArrayRequest — To receive JSON Array from the Server
StringRequest — To retrieve response body as String (ideally if you intend to parse the response by yourself)
JsonObjectRequest
这个类可以用来发送和接收JSON对象。这个类的一个重载构造函数允许设置适当的请求方法(DELETE,GET,POST和PUT)。如果您正在使用一个RESTful服务端,可以使用这个类。下面的示例显示如何使GET和POST请求GET请求:
final String URL = "/volley/resource/12"; // pass second argument as "null" for GET requests JsonObjectRequest req = new JsonObjectRequest(URL, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { VolleyLog.v("Response:%n %s", response.toString(4)); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { VolleyLog.e("Error: ", error.getMessage()); } }); // add the request object to the queue to be executed ApplicationController.getInstance().addToRequestQueue(req);
POST请求:final String URL = "/volley/resource/12"; // Post params to be sent to the server HashMap<String, String> params = new HashMap<String, String>(); params.put("token", "AbCdEfGh123456"); JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params), new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { VolleyLog.v("Response:%n %s", response.toString(4)); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { VolleyLog.e("Error: ", error.getMessage()); } }); // add the request object to the queue to be executed ApplicationController.getInstance().addToRequestQueue(req);
JsonArrayRequest
这个类可以用来接受 JSON Arrary,不支持JSON Object。这个类现在只支持 HTTP GET。由于支持GET,你可以在URL的后面加上请求参数。类的构造函数不支持请求参数final String URL = "/volley/resource/all?count=20"; JsonArrayRequest req = new JsonArrayRequest(URL, new Response.Listener<JSONArray> () { @Override public void onResponse(JSONArray response) { try { VolleyLog.v("Response:%n %s", response.toString(4)); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { VolleyLog.e("Error: ", error.getMessage()); } }); // add the request object to the queue to be executed ApplicationController.getInstance().addToRequestQueue(req);
StringRequest
这个类可以用来从服务器获取String,如果想自己解析请求响应可以使用这个类,例如返回xml数据。它还可以使用重载的构造函数定制请求final String URL = "/volley/resource/recent.xml"; StringRequest req = new StringRequest(URL, new Response.Listener<String>() { @Override public void onResponse(String response) { VolleyLog.v("Response:%n %s", response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { VolleyLog.e("Error: ", error.getMessage()); } }); // add the request object to the queue to be executed ApplicationController.getInstance().addToRequestQueue(req);4.取消请求
Volley提供了强大的API取消未处理或正在处理的请求。取消请求最简单的方法是调用请求队列cancelAll(tag)的方法,前提是你在添加请求时设置了标记。这样就能使标签标记的请求挂起。
给请求设置标签:request.setTag("My Tag");
使用ApplicationController添加使用了标签的请求到队列中:ApplicationController.getInstance().addToRequestQueue(request, "My Tag");
取消所有指定标记的请求:mRequestQueue.cancelAll("My Tag");5.重试失败的请求,自定义请求超时
Volley中没有指定的方法来设置请求超时时间,可以设置RetryPolicy 来变通实现。DefaultRetryPolicy类有个initialTimeout参数,可以设置超时时间。要确保最大重试次数为1,以保证超时后不重新请求。
Setting Request Timeout
request.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 1, 1.0f));
设置请求头(HTTP headers) 如果你想失败后重新请求(因超时),您可以指定使用上面的代码,增加重试次数。注意最后一个参数,它允许你指定一个退避乘数可以用来实现“指数退避”来从RESTful服务器请求数据。
有时候需要给HTTP请求添加额外的头信息,一个常用的例子是添加 “Authorization”到HTTP 请求的头信息。Volley请求类提供了一个 getHeaers()的方法,重载这个方法可以自定义HTTP 的头信息。添加头信息:
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params), new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { // handle response } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // handle error } }) { @Override public Map<String, String> getHeaders() throws AuthFailureError { HashMap<String, String> headers = new HashMap<String, String>(); headers.put("CUSTOM_HEADER", "Yahoo"); headers.put("ANOTHER_CUSTOM_HEADER", "Google"); return headers; } };6.使用Cookies
Volley中没有直接的API来设置cookies,Volley的设计理念就是提供干净、简洁的API来实现RESTful HTTP请求,不提供设置cookies是合理的。
下面是修改后的ApplicationController类,这个类修改了getRequestQueue()方法,包含了 设置cookie方法,这些修改还是有些粗糙// http client instance private DefaultHttpClient mHttpClient; 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) { // Create an instance of the Http client. // We need this in order to access the cookie store mHttpClient = new DefaultHttpClient(); // create the request queue mRequestQueue = Volley.newRequestQueue(this, new HttpClientStack(mHttpClient)); } return mRequestQueue; } /** * Method to set a cookie */ public void setCookie() { CookieStore cs = mHttpClient.getCookieStore(); // create a cookie cs.addCookie(new BasicClientCookie2("cookie", "spooky")); } // add the cookie before adding the request to the queue setCookie(); // add the request to the queue mRequestQueue.add(request);7.错误处理
正如前面代码看到的,在创建一个请求时,需要添加一个错误监听onErrorResponse。如果请求发生异常,会返回一个VolleyError实例。
以下是Volley的异常列表:
AuthFailureError:如果在做一个HTTP的身份验证,可能会发生这个错误。
NetworkError:Socket关闭,服务器宕机,DNS错误都会产生这个错误。
NoConnectionError:和NetworkError类似,这个是客户端没有网络连接。
ParseError:在使用JsonObjectRequest或JsonArrayRequest时,如果接收到的JSON是畸形,会产生异常。
SERVERERROR:服务器的响应的一个错误,最有可能的4xx或5xx HTTP状态代码。
TimeoutError:Socket超时,服务器太忙或网络延迟会产生这个异常。默认情况下,Volley的超时时间为2.5秒。如果得到这个错误可以使用RetryPolicy。
可以使用一个简单的Help类根据这些异常提示相应的信息: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); } }总结:
Volley是一个非常好的库,你可以尝试使用一下,它会帮助你简化网络请求,带来更多的益处。
转载自:http://www.tuicool.com/articles/3IJfIjV
相关文章推荐
- 【开源项目13】Volley框架 以及 设置request超时时间
- 【开源项目13】Volley框架 以及 设置request超时时间
- 【开源项目13】Volley框架 以及 设置request超时时间
- Volley框架 以及 设置request超时时间
- Volley框架 以及 设置request超时时间
- 基于XSocket框架的socket编程技巧(设置连接的超时时间和最大空闲时间)
- php-fpm超时时间设置request_terminate_timeout分析
- 给XMLHttpRequest设置超时时间
- apache axis 框架处理https请求时超时时间设置问题
- 利用okhttp3 给Retrofit2添加统一请求头 以及设置请求超时时间
- Android网络框架-Volley(二) RequestQueue源码分析以及建立一个RequestQueue
- andriod xutils设置请求超时时间 以及设置请求结果缓存时间
- 给XMLHttpRequest设置超时时间
- 修改volley默认超时时间以及重连次数
- Android去掉标题栏和全屏以及设置修改Android超时休眠时间
- Apache HttpClient设置请求超时时间和返回超时时间,以及超时重试
- python TCPServer, StreamRequestHandler设置超时时间timeout
- XMLHttpRequest设置超时时间
- ios AFNetworking https 认证以及请求超时时间设置
- 修改volley默认超时时间以及重连次数