6

Gson について私が気に入らなかった点の 1 つは、アイテムまたはアイテムのリストを取得するかどうかに基づいて、Class オブジェクトまたは TypeToken を渡す必要があるという事実です。現在、Gson で Volley を使用しようとすると、この問題が解決せず、両方に使用できる GsonRequest クラスを作成しようとしています。

私の解決策は非常に醜く、2 つの異なるコンストラクターです。1 つはClass<T>パラメーターを取得し、もう 1 つはパラメーターを取得しTypeます。次に、フィールドのいずれかparseNetworkResponsegson.fromJsonが呼び出されますが、いずれかが である必要があることに注意してnullください。

これをより良い方法で実装する方法について何か考えはありますか? GsonRequest( aと a がGsonCollectionRequestほぼ等しいクラスを持つのは好きではありません)

ここに私のコード:

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);
    }

}
4

3 に答える 3

5

次のメソッドを使用して、JSON リストを解析しました。まず、コンストラクターで Class を送信せず、代わりに Reflect パッケージから Type クラスを渡します。

私のクラスは次のようになります。

public class DownloadRequest<T> extends Request<T> {

private final Gson gson = new Gson();
private final Type type;
private final Map<String, String> params;
private final Response.Listener<T> listener;

public DownloadRequest(int method, String url, Map<String, String> params, Type type, Response.Listener<T> listener, Response.ErrorListener errorListener) {
    super(method, url, errorListener);
    this.type = type;
    this.params = params;
    this.listener = listener;
}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse networkResponse) {

    try {
        String json = new String(networkResponse.data, HttpHeaderParser.parseCharset(networkResponse.headers));
        T parseObject = gson.fromJson(json, type);
        return Response.success(parseObject,HttpHeaderParser.parseCacheHeaders(networkResponse));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return null;
}

@Override
protected void deliverResponse(T t) {
    listener.onResponse(t);
}

}

T parseObject = gson.fromJson(json, type);Request.success メソッドを呼び出す前に、この行を設定することが重要です。

于 2014-12-10T00:34:13.183 に答える
3

TypeToken を Type パラメーターとして使用して、新しい GsonRequest を作成できます。

この GsonRequest のような一般的な GsonRequest を使用します

Gson クラスの簡単なリクエストを作成します...

new GsonRequest<MyClass>(Request.Method.GET, uriBuilder.build().toString(),
                    MyClass.class, null, mResponseListener, mReponseErrorListener));

またはArrayListのタイプを作成します...

Type type = new TypeToken<ArrayList<MyClass>>() {}.getType();
new GsonRequest<ArrayList<MyClass>>(Request.Method.GET, uriBuilder.build().toString(),
                    type, null, mResponseListListener, mReponseErrorListener));
于 2014-03-27T12:09:44.670 に答える