實(shí)現(xiàn)一個(gè)自定義 Request
這節(jié)課描述了如何實(shí)現(xiàn)你自己的 request 類型,那些 Volley 不支持的的類型
寫一個(gè)自定義 Request
Volley 工具盒里實(shí)現(xiàn)了大都數(shù)類型 request穷吮,你不需要實(shí)現(xiàn)自定義 Request
如果你的 response 數(shù)據(jù)類型是一個(gè) string,image,或者 JSON
如果你需要實(shí)現(xiàn)自定義 request闪萄,下面是你需要做的:
繼承
Request<T>
類扣草,<T>
代表 request 期望 parsed response 的類型蒲列,所以如果 parsed response 是一個(gè) string娄柳,例如,創(chuàng)建一個(gè)繼承自Request<T>
的類粮坞,查看 Volley 工具箱里的類 繼承自Request<T>
的StringRequest
和ImageRequest
例子實(shí)現(xiàn)抽象方法
parseNetworkResponse
和deliverResponse
,下面描述更多實(shí)現(xiàn)細(xì)節(jié)
parseNetworkResponse
一個(gè) Response
封裝了一個(gè)需要傳遞的 parsed response初狰,比如給定的類型(string莫杈,image 或 JSON),這里有個(gè)實(shí)現(xiàn) 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()
攜帶一個(gè)包含以字節(jié)數(shù)組表示的response payloadNetworkResponse
參數(shù)奢入,HTTP 狀態(tài)碼筝闹,和一個(gè)響應(yīng)消息報(bào)頭你的實(shí)現(xiàn)必須返回一個(gè)包含類型化的 response 對(duì)象和 cache 元數(shù)據(jù)或者一個(gè)錯(cuò)誤(比如響應(yīng)解析失斚边丁)的
Response<T>
如果你的協(xié)議里沒有 non-standard cache 響應(yīng)消息報(bào)頭字段,你可以自己構(gòu)建一個(gè) Cache.Entry
关顷,但是大都數(shù)請(qǐng)求可以像這樣:
return Response.success(myDecodedObject,
HttpHeaderParser.parseCacheHeaders(response));
Volley 在 worker thread 中調(diào)用 parseNetworkResponse()
糊秆,這樣確保耗時(shí)的解析操作不會(huì)阻塞 UI thread ,例如 解碼一張 JPEG 到一個(gè) bitmap 中.
deliverResponse
Volley 在 main thread 中回調(diào)該方法并返回一個(gè)在 parseNetworkResponse()
方法中返回的對(duì)象议双,大多數(shù) request 回調(diào)類似這樣痘番,例如:
protected void deliverResponse(T response) {
listener.onResponse(response);
Example:GsonRequest
Gson 是一個(gè)使用 Java 反射在 Jave 對(duì)象和 JSON 間互轉(zhuǎn)的 library,你可以定義與 JSON keys 名稱相同的 Java objects平痰,傳遞這個(gè) object 的 class 對(duì)象到 Gson汞舱,Gson 會(huì)自動(dòng)為你的 object 填充相關(guān)字段,這里有一個(gè)完全實(shí)現(xiàn) Volley request并使用 Gson 來(lái)解析的例子:
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 獲取更多信息