One thing that I never liked about Gson is that you need to pass a Class or TypeToken object based on if you get an element or list of elements. Now, when you try to use Volley with Gson, this problem persists, and I'm trying to create a GsonRequest class that can be used for both things.
My solution is pretty ugly, two different constructors: one gets a Class<T> parameter, and the other gets Type parameters. Then in parseNetworkResponse , gson.fromJson is called with one of the fields, meaning that you need to be null .
Any idea on how to implement this better? (I don't like having GsonRequest and GsonCollectionRequest almost equal classes)
My code is here:
public class GsonRequest<T> extends Request<T> { private final Gson gson; private final Class<T> clazz; private final Type type; private final Listener<T> listener; private final Map<String, String> headers; private final Map<String, String> params; public GsonRequest(int method, String url, Gson gson, Class<T> clazz, Map<String, String> headers, Map<String, String> params, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); this.gson = gson; this.clazz = clazz; this.type = null; this.listener = listener; this.headers = headers; this.params = params; } public GsonRequest(int method, String url, Gson gson, Type type, Map<String, String> headers, Map<String, String> params, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); this.gson = gson; this.clazz = null; this.type = type; this.listener = listener; this.headers = headers; this.params = params; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return this.headers != null ? this.headers : super.getHeaders(); } @Override protected Map<String, String> getParams() throws AuthFailureError { return this.params != null ? this.params : super.getParams(); } @Override protected Response<T> parseNetworkResponse(NetworkResponse response) { try { if (this.clazz != null) { return Response.success( this.gson.fromJson(new String(response.data, HttpHeaderParser.parseCharset(response.headers)), this.clazz), HttpHeaderParser.parseCacheHeaders(response)); } else { return (Response<T>) Response.success( this.gson.fromJson(new String(response.data, HttpHeaderParser.parseCharset(response.headers)), this.type), HttpHeaderParser.parseCacheHeaders(response)); } } catch (JsonSyntaxException e) { e.printStackTrace(); return Response.error(new ParseError(e)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(T response) { this.listener.onResponse(response); } }