实现一个自定义 Request
这节课描述了如何实现你自己的 request 类型,那些 Volley 不支持的的类型
写一个自定义 Request
Volley 工具盒里实现了大都数类型 request,你不需要实现自定义 Request
如果你的 response 数据类型是一个 string,image,或者 JSON
如果你需要实现自定义 request,下面是你需要做的:
继承
Request<T>
类,<T>
代表 request 期望 parsed response 的类型,所以如果 parsed response 是一个 string,例如,创建一个继承自Request<T>
的类,查看 Volley 工具箱里的类 继承自Request<T>
的StringRequest
和ImageRequest
例子实现抽象方法
parseNetworkResponse
和deliverResponse
,下面描述更多实现细节
parseNetworkResponse
一个 Response
封装了一个需要传递的 parsed response,比如给定的类型(string,image 或 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
...
}
注意:
parseNetworkResponse()
携带一个包含以字节数组表示的response payloadNetworkResponse
参数,HTTP 状态码,和一个响应消息报头你的实现必须返回一个包含类型化的 response 对象和 cache 元数据或者一个错误(比如响应解析失败)的
Response<T>
如果你的协议里没有 non-standard cache 响应消息报头字段,你可以自己构建一个 Cache.Entry
,但是大都数请求可以像这样:
return Response.success(myDecodedObject,
HttpHeaderParser.parseCacheHeaders(response));
Volley 在 worker thread 中调用 parseNetworkResponse()
,这样确保耗时的解析操作不会阻塞 UI thread ,例如 解码一张 JPEG 到一个 bitmap 中.
deliverResponse
Volley 在 main thread 中回调该方法并返回一个在 parseNetworkResponse()
方法中返回的对象,大多数 request 回调类似这样,例如:
protected void deliverResponse(T response) {
listener.onResponse(response);
Example:GsonRequest
Gson 是一个使用 Java 反射在 Jave 对象和 JSON 间互转的 library,你可以定义与 JSON keys 名称相同的 Java objects,传递这个 object 的 class 对象到 Gson,Gson 会自动为你的 object 填充相关字段,这里有一个完全实现 Volley request并使用 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 获取更多信息