Eine Sache, die ich an Gson nie gemocht habe, ist die Tatsache, dass Sie ein Klassenobjekt oder ein TypeToken basierend darauf übergeben müssen, wenn Sie einen Gegenstand oder eine Liste von Gegenständen bekommen . Nun, wenn ich versuche, Volley mit Gson zu benutzen, bleibt dieses Problem bestehen und ich versuche eine GsonRequest-Klasse zu erstellen, die für beide Dinge verwendet werden kann.Verwenden von Volley und Gson: Objekt- und Elementliste analysieren
Meine Lösung ist ziemlich hässlich, zwei verschiedene Konstrukteure: eine bekommt einen Class<T>
Parameter und eine andere erhält eine Type
Parameter. Dann wird in der parseNetworkResponse
, gson.fromJson
mit einem der Felder aufgerufen, wobei zu beachten ist, dass man null
sein muss.
Haben Sie eine Idee, wie Sie dies besser umsetzen können? (Ich weiß nicht wie ein GsonRequest
und eine GsonCollectionRequest
fast gleich Klassen mit)
Mein Code, hier:
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);
}
}
Die Klasse 'Class' implementiert tatsächlich die' Type'-Schnittstelle, so dass Sie nicht wirklich einen Konstruktor haben, der 'Class' als Argument akzeptiert. –
Humm ... ich war mir fast sicher, dass ich einen Fehler bekommen hatte, indem ich einen 'Type' an' gson.fromJson' übergeben habe, wenn ich nur ein Element geparst haben wollte. Wie auch immer, ich habe es gerade mit 'Type' ausprobiert und es hat funktioniert, vielleicht muss ich nur' Type' verwenden, wie du sagst. Post es als Antwort und ich werde es akzeptieren :) – luixal
Werfen Sie einen Blick auf diesen Artikel, der genau das erklärt. https://goo.gl/nl2DfN – Sotti