Volley Lesson 4 -Implementing a Custom Request(译)

原文:http://developer.android.com/training/volley/request-custom.html

这边文章主要描述如何实现一个自己的request类型,实现Volley默认并不支持的功能。

Write a Custom Request

大多数时候,大多请求都不需要我们自己去实现一个Request,因为toolbox中默认有很多实现,比如string,image,JSON。

但如果我们要自己实现的时候,我们需要做的工作如下:

  • 继承Reqest<T>类,<T>为我们期待的请求结果的类型。比如我们想要response为String类型,那么我们就继承Request<String>即可。更多的可以参考Volley的toolbox类StringRequest和ImageReqeust来学习。
  • 实现抽象方法:parseNetworkResponse()和deliverResponse(),下面会更加细致的描述。

parseNetworkResponse

用来解析response。以下为一个例子。

@Override
protected Response<T> parseNetworkResponse(
        NetworkResponse response) {
    try {
        String json = new String(response.data,
        HttpHeaderParser.parseCharset(response.headers));
    return Response.success(gson.fromJson(json, clazz),
    HttpHeaderParser.parseCacheHeaders(response));
    }
    // handle errors
...
}

需要注意以下的事情:

  • parseNetworkResponse()有一个参数NetworkResponse,其中包括了response的返回值比如byte[],HTTP状态码,response headers
  • 方法的实现必须要返回一个Response<T>,其中包含了我们期待的返回值的类型,cache的元信息,或者失败的信息。

如果我们的协议没有标准的cache定义,那么我们可以自己构建Cache.Entry,对于大多数请求以下的代码可以实现:

return Response.success(myDecodedObject,
        HttpHeaderParser.parseCacheHeaders(response));

Volley会从worker thread调用parseNetworkResponse()。这就保证了其中耗时的操作不会阻塞UI线程。

deliverResponse

Volley会在parseNetworkResponse()完成的时候在main线程中调用callback接口,比如:

protected void deliverResponse(T response) {
        listener.onResponse(response);

 

Example: GsonRequest

Gson是一个方便的类通过反射实现Java类和JSON的转换。You can define Java objects that have the same names as their corresponding JSON keys, pass Gson the class object, and Gson will fill in the fields for you. Here’s a complete implementation of a Volley request that uses Gson for parsing:

public class GsonRequest<T> extends Request<T> {
    private final Gson gson = new Gson();
    private final Class<T> clazz;
    private final Map<String, String> headers;
    private final Listener<T> listener;

    /**
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url URL of the request to make
     * @param clazz Relevant class object, for Gson's reflection
     * @param headers Map of request headers
     */
    public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
            Listener<T> listener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.clazz = clazz;
        this.headers = headers;
        this.listener = listener;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return headers != null ? headers : super.getHeaders();
    }

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

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        try {
            String json = new String(
                    response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(
                    gson.fromJson(json, clazz),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        }
    }
}

About: happyhls


发表评论

电子邮件地址不会被公开。 必填项已用*标注