Jedną z rzeczy, których nigdy nie lubiłem o Gsonie, jest fakt, że musisz przekazać obiekt klasy lub typToken na podstawie, jeśli dostajesz przedmiot lub listę przedmiotów . Teraz, próbując użyć Volley z Gsonem, ten problem utrzymuje się i próbuję utworzyć klasę GsonRequest, która może być użyta dla obu rzeczy.Używanie Volley i Gson: Analiza pozycji i listy przedmiotów
Moje rozwiązanie jest dość brzydkie, dwa różne konstruktory: jeden pobierający parametr Class<T>
, a drugi pobierający parametry Type
. Następnie w nazwie parseNetworkResponse
, gson.fromJson
jest wywoływane z jednym z tych pól, pamiętając, że jeden musi być null
.
Każdy pomysł, jak lepiej to wdrożyć? (Nie lubię o GsonRequest
a GsonCollectionRequest
niemal równych klas)
Mój kod tutaj:
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);
}
}
Klasa 'Klasa' faktycznie implementuje interfejs' Type', więc naprawdę nie konstruktor, który przyjmuje argument "Klasa" jako argument. –
Humm ... byłem prawie pewien, że dostałem jakiś błąd, przekazując 'Type' do' gson.fromJson', kiedy chciałem, aby jakiś element został sparsowany. W każdym razie, właśnie wypróbowałem to przy użyciu 'Type' i zadziałało, więc może potrzebuję użyć' Type', jak mówisz. Napisz to jako odpowiedź, a ja ją przyjmuję :) – luixal
Zobacz ten artykuł, który dokładnie to wyjaśnia. https://goo.gl/nl2DfN – Sotti