您的位置:首页 > 产品设计 > UI/UE

Volley简单学习使用二——Request

2015-06-17 16:30 483 查看
一、首先从每个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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: