原文链接:Implementing a Custom Request
这节课教你:
- 写一个自定义的请求
这节课描述了如何实现自定义的请求类型,这些请求类型不是Volley现成的(out-of-the-box)支持。
写一个自定义的请求
多数请求在(Volley)工具箱中都有随时可用的(ready-to-use)实现;如果响应是字符串、图像或者JSON,那你大可不必实现自定义的Request
。
当需要自己实现一个request时,下面的步骤是必须的:
继承
Request<T>
类,<T>
表示request期望解析的response的类型。所以,如果解析的response是字符串,打个比方,创建自定义的request通过继承Request<String>
。以Volley的toolbox包中的StringRequest
和ImageRequest
为例,它们继承自Request<T>
。实现抽象方法
parseNetworkResponse()
和deliverResponse()
,下面会详细描述
parseNetworkResponse
Response
类使用给定的类型(比如字符串、图片或JSON)封装了一个解析了的响应,用于传递。下面是parseNetworkResponse()
的实现例子:
@Override
protected Response<T> parseNetworkResponse(
NetworkResponse response) {
try {
String json = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
}
// handle errors
...
}
注意下面的几条:
-
NetworkResponse
作为parseNetworkResponse()
的参数,包含了byte[]类型的响应负载(译注:就是响应体)、HTTP状态码和响应头。 - 实现方法必须返回一个
Response<T>
,它包含了你指定的类型的响应对象和缓存元数据或如解析出错时的错误对象。
如果你的协议中没有标准的缓存说明,你可以自己构建一个Cache.Entry
,但是大多数的请求只要如下这样就够了(?):
return Response.success(myDecodedObject,
HttpHeaderParser.parseCacheHeaders(response));
Volley从工作线程调用parseNetworkResponse()
。这样保证了昂贵的解析操作,比如解码一个JPEG图片成Bitmap,不会中断UI线程。
deliverResponse
Volley将parseNetworkResponse()
中返回的对象传递到主线程。多数请求会在此调用一个回调接口,比如:
protected void deliverResponse(T response) {
listener.onResponse(response);
例子:GsonRequest
Gson是一个库,它通过反射技术实现Java对象和JSON之间的转化。你可以使用跟JSON的key相对应的名字创建java对象,然后传递给Gson对象,接着Gson就会帮你填充字段值。下面是一个关于Volley请求和使用Gson解析的完整例子:
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
*/
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
如果你愿意,Volley提供了可以直接用的JsonArrayRequest
和JsonArrayObject
类。查阅Using Standard Request Types获取更多信息。
项目源码下载 :点击下载
系列索引
- 【译】Volley官方文档五:实现一个自定义的Request
- 【译】Volley官方文档四:构建一个标准的Request
- 【译】Volley官方文档三:建立一个RequestQueue
- 【译】Volley官方文档二:发送一个简单的request
- 【译】Volley官方文档一:使用Volley传递网络数据
更新日志:
- 2016年03月21日
- 添加系列索引