Volley简单学习使用二——Request

来源:互联网 发布:Javaweb连接数据库 编辑:程序博客网 时间:2024/05/14 07:20
一、首先从每个POST或者GET请求的构造主体看起:XXXRequest
(一)StringRequest
源码如下:
public class StringRequest extends Request<String> {    private final Listener<String> mListener;     /**     * 可以看到最终构造请求交由Request类去实现,HTTP的请求和响应均是由Request去处理     *     * @param method the request {@link Method} to use;method在Request中给出了定义     * @param url URL to fetch the string at     * @param listener Listener to receive the String response     * @param errorListener Error listener, or null to ignore errors     */    public StringRequest(int method, String url, Listener<String> listener,            ErrorListener errorListener) {        super(method, url, errorListener);        mListener = listener;    }     /** 默认为GET请求的构造函数*/    public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {        this(Method.GET, url, listener, errorListener);    }    /** 这两个函数在父类Request均是abstract的*/    // 将服务器响应的数据进行回调    @Override    protected void deliverResponse(String response) {        mListener.onResponse(response);    }    // 对服务器响应发送的数据进行解析的函数,可以看到主体数据在NetworkResponse的data中    // 很明显返回的success函数中第一个函数即是解析后的数据    @Override    protected Response<String> parseNetworkResponse(NetworkResponse response) {        String parsed;        try {            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));        } catch (UnsupportedEncodingException e) {            parsed = new String(response.data);        }        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));    }}

(二)可以推理JSONObject也是相类似的实现,
public class JsonObjectRequest extends JsonRequest<JSONObject>public abstract class JsonRequest<T> extends Request<T>

1、先看JsonObjectRequest的定义:
public class JsonObjectRequest extends JsonRequest<JSONObject> {   /** 可以看到JsonObjectRequest最终构造请求也交由Request类去实现    *  整个代码结构与StringRequest大同小异*/    public JsonObjectRequest(int method, String url, JSONObject jsonRequest,            Listener<JSONObject> listener, ErrorListener errorListener) {        super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,                    errorListener);    }    public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,            ErrorListener errorListener) {        this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,                listener, errorListener);    }     /*deliverResponse在父类JsonRequest中给予了实现*/    @Override    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {        try {            String jsonString =                new String(response.data, HttpHeaderParser.parseCharset(response.headers));            return Response.success(new JSONObject(jsonString),                    HttpHeaderParser.parseCacheHeaders(response));        } catch (UnsupportedEncodingException e) {            return Response.error(new ParseError(e));        } catch (JSONException je) {            return Response.error(new ParseError(je));        }    }}
2、查看JsonRequest
public abstract class JsonRequest<T> extends Request<T> {    /** Request的编码格式. */    private static final String PROTOCOL_CHARSET = "utf-8";     /** Request的Content内容.*/    private static final String PROTOCOL_CONTENT_TYPE =        String.format("application/json; charset=%s", PROTOCOL_CHARSET);     private final Listener<T> mListener;    private final String mRequestBody;     /**     * Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()}     * or {@link #getPostParams()} is overridden (which defaults to POST).     */    public JsonRequest(int method, String url, String requestBody, Listener<T> listener,            ErrorListener errorListener) {        super(method, url, errorListener);//这些均与StringRequest相类似,无非是多了mRequestBody        mListener = listener;        mRequestBody = requestBody;    }     @Override    protected void deliverResponse(T response) {        mListener.onResponse(response);    }     @Override    abstract protected Response<T> parseNetworkResponse(NetworkResponse response);     /** 这里重写了request中的相对应函数,来实现构造Request的具体内容 */    @Override    public String getBodyContentType() {        return PROTOCOL_CONTENT_TYPE;    }     @Override    public byte[] getBody() {        try {            return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);        } catch (UnsupportedEncodingException uee) {            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",                    mRequestBody, PROTOCOL_CHARSET);            return null;        }    }}

(三)有上面可以总结出,构造XXXRequest的一般实践方式,

1、构造真正的Request交由父类Requset<XXX>去实现-- super(method, url, errorListener);

2、定义自己的Listener,用以deliverResponse

3、重写parseNetworkResponse函数来解析服务器响应返回的数据

(四)根据上面的分析,来定义自己的XXXRequest,比如XMLRequest来获取XML类型的返回数据,这里copy了

http://blog.csdn.net/guolin_blog/article/details/17612763中的代码

public class XMLRequest extends Request<XmlPullParser> {     /*********这里讲T替换成所需要解析成的数据类型***********/    private final Listener<XmlPullParser> mListener;     /*********这里与前面所述的流程基本完全相同************************/    public XMLRequest(int method, String url, Listener<XmlPullParser> listener,            ErrorListener errorListener) {        super(method, url, errorListener);        mListener = listener;    }     public XMLRequest(String url, Listener<XmlPullParser> listener,            ErrorListener errorListener) {        this(Method.GET, url, listener, errorListener);    }     @Override    protected Response<XmlPullParser> parseNetworkResponse(            NetworkResponse response) {        try {            /***************实现新的XMLRequset核心在于此,解析数据返回的数据,用以获取最终的解析结果*********************/            String xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();            XmlPullParser xmlPullParser = factory.newPullParser();            xmlPullParser.setInput(new StringReader(xmlString));            return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));        } catch (UnsupportedEncodingException e) {            return Response.error(new ParseError(e));        } catch (XmlPullParserException e) {            return Response.error(new ParseError(e));        }    }     @Override    protected void deliverResponse(XmlPullParser response) {        mListener.onResponse(response);    } }
其使用方式也与StringRequest大致相同,在Listener中可以添加对服务器response的数据的解析代码:
    private RequestQueue mRequestQueue;       mRequestQueue = Volley.newRequestQueue(this);    String url = "http://flash.weather.com.cn/wmaps/xml/china.xml";     Response.Listener<XmlPullParser> listener = new Response.Listener<XmlPullParser>() {        @Override        public void onResponse(XmlPullParser response) {            // 这里应该加上对于response的具体数据的解析            Log.d(TAG, response.toString());        }    };     Response.ErrorListener errorListener = new Response.ErrorListener() {        @Override        public void onErrorResponse(VolleyError error) {            Log.e(TAG, error.getMessage());        }    };     XMLRequest xmlRequest = new XMLRequest(url, listener, errorListener);    mRequestQueue.add(xmlRequest);

(五)回过头来看Request的原码

1、先看一下其构造函数,也是前面几个XXXRequest调用的构造函数:

public Request(int method, String url, Response.ErrorListener listener) {    mMethod = method;                        // 成员变量赋值    mUrl = url;    mErrorListener = listener;    setRetryPolicy(new DefaultRetryPolicy());// 设置重试策略     mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();}
附I、重试策略
public class DefaultRetryPolicy implements RetryPolicy {        ....    /** The default socket timeout in milliseconds */    public static final int DEFAULT_TIMEOUT_MS = 2500;//默认socket超时时间    /** The default number of retries */    public static final int DEFAULT_MAX_RETRIES = 1;  //默认重试次数    /** The default backoff multiplier */    public static final float DEFAULT_BACKOFF_MULT = 1f;//默认补偿系数     public DefaultRetryPolicy() {        this(DEFAULT_TIMEOUT_MS, DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_MULT);    }        ....}
setRetryPolicy即是一个简单的setter函数:
    /** The retry policy for this request. */    private RetryPolicy mRetryPolicy;     public void setRetryPolicy(RetryPolicy retryPolicy) {        mRetryPolicy = retryPolicy;    }
2、剩下的便是一连串的setter与getter函数,前面还用到的函数有:
    abstract protected Response<T> parseNetworkResponse(NetworkResponse response);       abstract protected void deliverResponse(T response);
可以看出这两个是abstract的,要求必须Override
3、JsonRequest中还Override了一些POST body相关函数,这些函数用以组织POST请求中的参数;具体使用时可以自行重载:
    private static final String DEFAULT_PARAMS_ENCODING = "UTF-8";       protected Map<String, String> getParams() throws AuthFailureError {        return null;    }       protected String getParamsEncoding() {        return DEFAULT_PARAMS_ENCODING;    }     public String getBodyContentType() {        return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();    }     /**     * Returns the raw POST or PUT body to be sent.     */    public byte[] getBody() throws AuthFailureError {        Map<String, String> params = getParams();// 由上面getParams方法的定义可以看出,要使用本方法,                                                 // 应该重载getParams方法,或者直接重载getBody()        if (params != null && params.size() > 0) {            return encodeParameters(params, getParamsEncoding());        }        returnnull;    }     /**     * Converts <code>params</code> into an application/x-www-form-urlencoded encoded string.     */    privatebyte[] encodeParameters(Map<String, String> params, String paramsEncoding) {        StringBuilder encodedParams = new StringBuilder();        try {            for (Map.Entry<String, String> entry : params.entrySet()) {                encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));                encodedParams.append('=');                encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));                encodedParams.append('&');            }            return encodedParams.toString().getBytes(paramsEncoding);        } catch (UnsupportedEncodingException uee) {            thrownew RuntimeException("Encoding not supported: " + paramsEncoding, uee);        }    }
1 0
原创粉丝点击