Una cosa che non mi è mai piaciuta di Gson è il fatto che devi passare un oggetto Class o TypeToken se stai ricevendo un oggetto o un elenco di oggetti . Ora, quando provo a usare Volley con Gson, questo problema persiste e sto cercando di creare una classe GsonRequest che possa essere utilizzata per entrambe le cose.Utilizzo di Volley e Gson: Parse voce e lista articoli
La mia soluzione è abbastanza brutta, due diversi costruttori: uno che ottiene un parametro Class<T>
e un altro che ottiene un parametro Type
. Quindi, nel numero parseNetworkResponse
, viene chiamato gson.fromJson
con uno dei campi, tenendo presente che uno deve essere null
.
Qualche idea su come implementarlo in un modo migliore? (Non mi piace avere un GsonRequest
e un GsonCollectionRequest
classi quasi uguali)
Il mio codice, qui:
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);
}
}
Classe 'Class' implementa effettivamente l'interfaccia' Tipo' quindi non si è realmente un costruttore che accetta 'Class' come argomento. –
Humm ... ero quasi sicuro di aver avuto qualche errore nel passare un 'Type' a' gson.fromJson' quando volevo solo un oggetto per essere analizzato. Comunque, l'ho appena provato usando 'Type' e ha funzionato così forse ho solo bisogno di usare' Type' come dici tu. Pubblicalo come risposta e lo accetto :) – luixal
Dai un'occhiata a questo articolo che spiega esattamente questo. https://goo.gl/nl2DfN – Sotti