Android Volley框架的使用(二)
此博文源码下载地址 https://github.com/Javen205/VolleyDemo.git
使用请求队列RequestQueue
Volley中的Request都需要添加到RequestQueue中才能执行,所以首先需要创建一个RequestQueue
RequestQueue = Volley.newRequestQueue(mContext);
通常情况在一个应用中需要统一管理一个请求队列,所以采用单例模式(注意:这不是必须的),创建一个类并在这个类中初始化RequestQueue
等核心对象,以及实现一些我们所需的方法;
代码如下:
package com.javen.volley; import android.content.Context;
import android.text.TextUtils; import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley; public class VolleyController { // 创建一个TAG,方便调试或Log
private static final String TAG = "VolleyController"; // 创建一个全局的请求队列
private RequestQueue reqQueue;
private ImageLoader imageLoader; // 创建一个static ApplicationController对象,便于全局访问
private static VolleyController mInstance; private Context mContext; private VolleyController(Context context) {
mContext=context;
} /**
* 以下为需要我们自己封装的添加请求取消请求等方法
*/ // 用于返回一个VolleyController单例
public static VolleyController getInstance(Context context) {
if (mInstance == null) {
synchronized(VolleyController.class)
{
if (mInstance == null) {
mInstance = new VolleyController(context);
}
}
}
return mInstance;
} // 用于返回全局RequestQueue对象,如果为空则创建它
public RequestQueue getRequestQueue() {
if (reqQueue == null){
synchronized(VolleyController.class)
{
if (reqQueue == null){
reqQueue = Volley.newRequestQueue(mContext);
}
}
}
return reqQueue;
} // public ImageLoader getImageLoader(){
// getRequestQueue();
// //如果imageLoader为空则创建它,第二个参数代表处理图像缓存的类
// if(imageLoader==null){
// imageLoader=new ImageLoader(reqQueue, new LruBitmapCache());
// }
// return imageLoader;
// } /**
* 将Request对象添加进RequestQueue,由于Request有*StringRequest,JsonObjectResquest...
* 等多种类型,所以需要用到*泛型。同时可将*tag作为可选参数以便标示出每一个不同请求
*/ public <T> void addToRequestQueue(Request<T> req, String tag) {
// 如果tag为空的话,就是用默认TAG
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req);
} public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
} // 通过各Request对象的Tag属性取消请求
public void cancelPendingRequests(Object tag) {
if (reqQueue != null) {
reqQueue.cancelAll(tag);
}
}
}
执行异步请求
上篇文章已经提到过,Volley主要提供了以下几种类型的异步请求:
- JsonObjectRequest 用来接收和发送JsonObject类型的数据
- JsonArrayRequest 用来接收和发送JsonArray类型的数据
- StringRequest 用来接收和发送响应主体为String的数据
JsonObjectRequest
这是一个用来发送和接收JSON
数据最常用的类,覆写这个类中的一些方法可以发送(GET,POST,DELETE,PUT)等适当的HTTP请求,常见操作代码示例:
final String url="http://xxx"; JsonObjectRequest req=new JsonObjectRequest(url,null,
new Response.Listener<JsonObject>(){
@Override
public void onResponse(JsonObject response){
//正确响应时回调此函数
} },new ResponseError.Listener(){ @Override
public void onErrorResponse(VolleyError error){
//未正确响应时回调此函数
}
});
//将请求添加至全局RequestQueue
VolleyController.getInstance(context).addToRequestQueue(req);
发送包含HTTP 请求方法(Post
Put
Get
Delete
)的 Request:
如果我们想要发送Post,Delete等请求,可通过一个带请求参数的
JsonObject对象
来实现
//用来保存post参数
HashMap<String,String> params=new HashMap<String,String>();
params.put("user","xxx"); //new JsonObject(params) 作为 JsonObjectRequest 参数
JsonObjectRequest req=new JsonObjectRequest(url,
new JsonObject(params),
new Response.Listener<JsonObject>(){...},
new Response.ErrorListener(){...});
发送JsonArrayRequest
StringRequest
与JsonObjectRequest
类似:
JsonArrayRequest req=new JsonArrayRequest(url,
new Response.Listener<JsonArray>(){..},
new Response.ErrorListener(){..});
StringRequest req=new StringRequest(url,
new Response.Listener<String>(){..},
new Response.ErrorListener(){..});
取消Request
Volley框架提供了强大的API来支持取消正在等待或者运行的一个或多个请求,还记得我们先前提到的setTag()
方法吗,正是通过Tag来标示每个Request,我们特可以通过这个Tag来取消Request
//可以通过setTag方法为每一个Request添加tag
req.setTag("Tag");
//也可以在我们实现的添加进RequestQueue的时候设置
VolleyController.getInstance(context).cancelPendingRequests("Tag"); //取消Request
reqQueue.cancelAll("Tag");
//我们前面实现的方法
VolleyController.getInstance(context).cancelPendingRequests("Tag");
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
学习完上面三个方面的知识,我们就已经差不多掌握了Volley最常用的方法,如果想让你的应用更健壮,还需要了解Volley中的错误处理,设置请求失败重试机制和超时机制,设置请求优先级,设置请求头部等等
拓展部分
请求失败时的重试和请求自定义超时
Volley中提供了一个方案:可以通过Request对象调用setRetryPolicy()
方法,设置超时和重试请求
// 第一个代表超时时间:即超过20S认为超时,第三个参数代表最大重试次数,这里设置为1.0f代表如果超时,则不重试
req.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 1, 1.0f));
设置请求优先级
在实际开发中我们常常需要提高一些请求的优先级以便优先执行,可以通过覆写getPrioriity()方法
//优先级有LOW,NORMAL,HIGH,IMMEDIATE
private Priority priority = Priority.HIGH; StringRequest strReq = new StringRequest(Method.GET,
Const.URL_STRING_REQ,
new Response.Listener<String>() { @Override
public void onResponse(String response) {
Log.d(TAG, response.toString());
msgResponse.setText(response.toString());
hideProgressDialog();
}
}, new Response.ErrorListener() { @Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hideProgressDialog();
}
}) {
@Override
public Priority getPriority() {
return priority;
}
};
设置请求头部(HTTP 头部)
很多时候需要给HTTP Request添加头部,一个典型的场景就是基本的HTTP 授权认证,Request类中提供了getHeaders()
方法,你需要覆写并添加自己的自定义头部
@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;
}
错误处理
你可能已经注意到了在创建Request对象时,构造参数中有
new Response.ErrorListener()
,这就是典型的错误处理
volley中错误主要有以下几类:
- AuthFailureError — 基本的Http身份认证(授权)错误.
- NetworkError — 网络错误
- NoConnectionError — 网络连接错误.
- ParseError — 数据解析错误.
- ServerError — 服务端错误.
- TimeoutError — 超时错误.
你可以实现自己的错误处理类,用来返回具体的错误信息
public class VolleyErrorHelper { //用于返回具体错误信息,分辨错误类别
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);
} //判断是否是网络错误
private static boolean isNetworkProblem(Object error) {
return (error instanceof NetworkError) ||
(error instanceof NoConnectionError);
} //判断是否是服务端错误
private static boolean isServerProblem(Object error) {
return (error instanceof ServerError) ||
(error instanceof AuthFailureError);
} //处理服务端错误
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();
} return error.getMessage(); default:
return context.getResources().getString(R.string.generic_server_down);
}
}
return context.getResources().getString(R.string.generic_error);
}
}
总结:
综上,我们已经基本上学完了Volley框架的大部分知识,唯一还没有涉及到且比较重要的就是图像缓存方面的内容,将在下篇博客中介绍
参考资料:Asynchronous HTTP Requests in Android Using Volley blog
Android Volley框架的使用(二)的更多相关文章
- Android Volley框架的使用(1)
在Android开发中,经常要通过HTTP请求访问网络.为了使通过HTTP请求访问网络的过程更加简单,2013年提出了新的HTTP通信框架--Volley.Volley使用起来非常简单,适用于网络访问 ...
- Android Volley 框架的使用(一)
为什么要使用Volley框架 开发android应用很多时候都要涉及网络操作,Android SDK中提供了HttpClient 和 HttpUrlConnection两种方式用来处理网络操作,但当应 ...
- Android Volley框架的使用(三)
此博文源码下载地址 https://github.com/Javen205/VolleyDemo.git Image Request 为了更方便的使用Volley中的图片请求,我们同样先在Voll ...
- Android Volley框架的使用(四)图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)
在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...
- 035 Android Volley框架进行网络请求
1.volley入门介绍 开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行HTTP通 ...
- Android Multimedia框架总结(二十)MediaCodec状态周期及Codec与输入/输出Buffer过程(附实例)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53183718 前言:前面几节都是 ...
- Android View框架总结(二)View焦点
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52263256 前言:View框架写到第六篇,发现前面第二篇竟然没有, ...
- Android Volley框架的几种post提交请求方式
首先简单描述一下Google的Android开发团队在2013年推出的一个网络通信框架Volley.它的设计目标是进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如下载文件等,Vol ...
- Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例
前言:前面一篇我们介绍MediaPlayer相关方法,有人说,没有实际例子,看得不是很明白,今天在分析MediaPlayer时,顺带一个播放网络视频例子.可以自行试试.今天分析的都是下几篇介绍各个模块 ...
随机推荐
- <转+改>Web测试中关于登录的测试
请问,你为自己写过的用例怀疑过吗? 前两天听一个朋友说他同事写了100个用例,结果有92个是无效的,差点被公司开了,本人以前也写过不少用例,但现在忽然怀疑我的用例了,觉得越来越糊涂了,拿登陆框来说吧, ...
- 【转】linux之fsck命令
转自:http://www.linuxso.com/command/fsck.html 使用权限 : 超级使用者 使用方式 : fsck [-sACVRP] [-t fstype] [--] [fsc ...
- VS2013中修改.dll工程项目的.lib和.dll的输出路径
一个dll工程,生成的两个东西是我们需要的:.lib和.dll,在实际开发过程中我们往往希望这两个东西直接输出到特定文件夹,对于这两个的修改: 设置好之后,对于调用该dll的exe工程,将exe的输出 ...
- 50种方法优化SQL Server数据库查询
查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 ...
- no symbol version for module_layout
内核模块编译helloworld: no symbol version for module_layout, 尝试各种解决办法, 都没搞定, 版本也是对的. dmesg提示no symbol vers ...
- 调用openoffice Com组件转换成PDF
//例子 OpenOfficeExportToPDF('file:///C:/SourceFile.odt', 'file:///C:/TargetFile.pdf'); 必须为URL格式的路径 ...
- ACM2050前传
n在一个平面上有一个圆和n条直线,这些直线中每一条在圆内 同其他直线相交,假设没有3条直线相交于一点,试问这些直线 将圆分成多少区域. 使用递归 F(1)=2; F(n) = F(n-1)+n; ...
- LCA of a Binary Tree
236. Lowest Common Ancestor of a Binary Tree /** * 基础版 * 给定p,q都是在树中 * 有两种情况: * 1. p和q分布在LCA的两侧 * 2. ...
- sqlserver安装相关问题
最近在部署一个工程,数据库(sqlserver2005develop)遇到不少问题,下面将一一列出. 安装完毕后,无法连接到本地实例. 打开microsoft sql server 2005-> ...
- 轻松学习Linux之AWK使用初步
AWK最初是Unix平台上一种可以对文本进行逐行处理的编程语言,它来源于3个创作者的名字:Aho.(Peter)Weinberg和(Brain)Kernighan. 现在广泛应用于Linux,他与se ...