Volley HTTP库系列教程(5)自定义一个Volley请求
Implementing a Custom Request
1.This lesson teaches you to
2.Write a Custom Request
Most requests have ready-to-use implementations in the toolbox; if your response is a string, image, or JSON, you probably won't need to implement a customRequest
.
For cases where you do need to implement a custom request, this is all you need to do:
- Extend the
Request<T>
class, where<T>
represents the type of parsed response the request expects. So if your parsed response is a string, for example, create your custom request by extendingRequest<String>
. See the Volley toolbox classesStringRequest
andImageRequest
for examples of extendingRequest<T>
. - Implement the abstract methods
parseNetworkResponse()
anddeliverResponse()
, described in more detail below.
2.1 parseNetworkResponse
A Response
encapsulates a parsed response for delivery, for a given type (such as string, image, or JSON). Here is a sample implementation of parseNetworkResponse()
:
1 @Override 2 protected Response<T> parseNetworkResponse( 3 NetworkResponse response) { 4 try { 5 String json = new String(response.data, 6 HttpHeaderParser.parseCharset(response.headers)); 7 return Response.success(gson.fromJson(json, clazz), 8 HttpHeaderParser.parseCacheHeaders(response)); 9 } 10 // handle errors 11 //... 12 }
Note the following:
parseNetworkResponse()
takes as its parameter aNetworkResponse
, which contains the response payload as a byte[], HTTP status code, and response headers.- Your implementation must return a
Response<T>
, which contains your typed response object and cache metadata or an error, such as in the case of a parse failure.
If your protocol has non-standard cache semantics, you can build a Cache.Entry
yourself, but most requests are fine with something like this:
return Response.success(myDecodedObject, HttpHeaderParser.parseCacheHeaders(response));
Volley calls parseNetworkResponse()
from a worker thread. This ensures that expensive parsing operations, such as decoding a JPEG into a Bitmap, don't block the UI thread.
2.2 deliverResponse
Volley calls you back on the main thread with the object you returned in parseNetworkResponse()
. Most requests invoke a callback interface here, for example:
protected void deliverResponse(T response) { listener.onResponse(response);
2.3 Example: GsonRequest
Gson is a library for converting Java objects to and from JSON using reflection. You can define Java objects that have the same names as their corresponding JSON keys, pass Gson the class object, and Gson will fill in the fields for you. Here's a complete implementation of a Volley request that uses Gson for parsing:
1 import java.io.UnsupportedEncodingException; 2 import java.util.Map; 3 4 import com.android.volley.AuthFailureError; 5 import com.android.volley.NetworkResponse; 6 import com.android.volley.ParseError; 7 import com.android.volley.Request; 8 import com.android.volley.Response; 9 import com.android.volley.Response.ErrorListener; 10 import com.android.volley.Response.Listener; 11 import com.android.volley.toolbox.HttpHeaderParser; 12 import com.google.gson.Gson; 13 import com.google.gson.JsonSyntaxException; 14 15 public class GsonRequest<T> extends Request<T> { 16 private final Gson gson = new Gson(); 17 private final Class<T> clazz; 18 private final Map<String, String> headers; 19 private final Listener<T> listener; 20 21 /** 22 * Make a GET request and return a parsed object from JSON. 23 * 24 * @param url URL of the request to make 25 * @param clazz Relevant class object, for Gson's reflection 26 * @param headers Map of request headers 27 */ 28 public GsonRequest(String url, Class<T> clazz, Map<String, String> headers, 29 Listener<T> listener, ErrorListener errorListener) { 30 super(Method.GET, url, errorListener); 31 this.clazz = clazz; 32 this.headers = headers; 33 this.listener = listener; 34 } 35 36 @Override 37 public Map<String, String> getHeaders() throws AuthFailureError { 38 return headers != null ? headers : super.getHeaders(); 39 } 40 41 @Override 42 protected void deliverResponse(T response) { 43 listener.onResponse(response); 44 } 45 46 @Override 47 protected Response<T> parseNetworkResponse(NetworkResponse response) { 48 try { 49 String json = new String(response.data,HttpHeaderParser.parseCharset(response.headers)); 50 return Response.success(gson.fromJson(json, clazz),HttpHeaderParser.parseCacheHeaders(response)); 51 } catch (UnsupportedEncodingException e) { 52 return Response.error(new ParseError(e)); 53 } catch (JsonSyntaxException e) { 54 return Response.error(new ParseError(e)); 55 } 56 } 57 }
使用代码
1 /* 2 * 自定义一个request 3 */ 4 public void onClickCustomRequest(View btn){ 5 String url = "http://192.168.1.100/gsonrequest.php";//返回json数据 6 //1,得到一个RequestQueue 7 RequestQueue queue = Volley.newRequestQueue(this); 8 //2,构造一个自定义请求,返回Person,Person是自定义的类 9 //3,构造请求的header 10 Map<String,String> headers = new HashMap<String, String>(); 11 headers.put("XXX", "XXX"); 12 headers.put("XXX", "XXX"); 13 14 //4,构造自定义的请求 15 GsonRequest<Person> jsonRequest = new GsonRequest<Person>(url, Person.class, headers 16 , new Response.Listener<Person>() { 17 @Override 18 public void onResponse(Person person) { 19 output.append("onResponse"); 20 } 21 }, new Response.ErrorListener() { 22 @Override 23 public void onErrorResponse(VolleyError paramVolleyError) { 24 output.append(paramVolleyError.getMessage()); 25 } 26 }); 27 //5,将请求加到请求队列中. 28 queue.add(jsonRequest); 29 }
Volley provides ready-to-use JsonArrayRequest
and JsonArrayObject
classes if you prefer to take that approach. See Using Standard Request Types for more information.