您的位置:首页 > 理论基础 > 计算机网络

Volley框架的基本解读(七)

2016-05-26 09:44 477 查看
在前面六篇博客中,我们已经将Volley框架主线全部走完,今天我们来讲讲Volley框架中两个十分重要的角色Request与Response,这两个类之所以放到最后来讲,一方面对Volley没有一个清晰的认识,可能会比较难懂,另方面好戏不都是压轴的吗?

我们先看Request的源码:

public abstract class Request<T> implements Comparable<Request<T>>


它是一个抽象类,并实现了Comparable用于比较排序,还记得RequestQueue中的mCacheQueue与mNetworkQueue这两个优先级队列吗?实现Comparable接口就是为了能在队列中排序,而从实现某些Request的优先请求。

我们还有先从构造方法开始看起:

public Request(String url, Response.ErrorListener listener) {
this(Method.DEPRECATED_GET_OR_POST, url, listener);
}


这个构造方法有两个参数,分别是URL与错误回调,它调用了另一个构造方法,Method是Request的一个内部接口,我们看看:

/**
* Supported request methods.
* 支持的请求方式
*/
public interface Method {
int DEPRECATED_GET_OR_POST = -1;
int GET = 0;
int POST = 1;
int PUT = 2;
int DELETE = 3;
}

可见内部定义了四种支持的请求方式,DEPRECATED_GET_OR_POST这个大家可以无视,我也不是很理解,接着看:

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

这里为我们创建了一个重试策略并绑定在request中,mDefaultTrafficStatsTag是用于流量监控的唯一标识,通过URL产生。

Request内部定义了很多公共方法,比较重要的有这么几个,我们一起来看看:

/**
* Returns true if this request has been canceled.
*
* 是否取消该request
*/
public boolean isCanceled() {
return mCanceled;
}
/**
* Mark this request as canceled.  No callback will be delivered.
* 取消请求
*/
public void cancel() {
mCanceled = true;
}


在之前的源码解析中我们经常可以看到isCanceled,现在我们知道它仅仅只是做了一个标识而已。

/**
* Returns the cache key for this request. By default, this is the URL.
* 获取缓存的Key,就是URL
*/
public String getCacheKey() {
return getUrl();
}
/**
* Returns the URL of this request.
* 请求URL
*/
public String getUrl() {
return mUrl;
}


getCacheKey该方法在缓存解析的时候出现过,缓存的Key就是URL。

/**
* Returns a Map of parameters to be used for a POST or PUT request. Can throw
* {@link AuthFailureError} as authentication may be required to provide these values.
*
* <p>Note that you can directly override {@link #getBody()} for custom data.</p>
*
* @throws AuthFailureError in the event of auth failure
*
* 空请求体,子类可以复写该方法,如果子类需要的话
*/
protected Map<String, String> getParams() throws AuthFailureError {
return null;
}

public byte[] getBody() throws AuthFailureError {
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
return encodeParameters(params, getParamsEncoding());
}
return null;
}
private byte[] 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) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}

该方法用于POST请求,添加请求体。

/**
* Priority values. Requests will be processed from higher priorities to
* lower priorities, in FIFO order.
*
* 优先级
*/
public enum Priority {
LOW,
NORMAL,
HIGH,
IMMEDIATE
}
/**
* Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default.
*
* 获取优先级,默认正常
*/
public Priority getPriority() {
return Priority.NORMAL;
}


Request的优先级,当你有急切请求需求的时候,就可以设置它。

/**
* Mark this request as having a response delivered on it. This can be used
* later in the request's lifetime for suppressing identical responses.
*
* 标记分发事件完毕
*/
public void markDelivered() {
mResponseDelivered = true;
}

它同样是以个标记。

@Override
public int compareTo(Request<T> other) {
Priority left = this.getPriority();
Priority right = other.getPriority();

// High-priority requests are "lesser" so they are sorted to the front.
// Equal priorities are sorted by sequence number to provide FIFO ordering.
// 如果优先级相等,按序列号排序,序列号高则放在后面
return left == right ?
this.mSequence - other.mSequence :
right.ordinal() - left.ordinal();
}

这里是重点,request的比较,优先级优先,如果优先级相同,再比较序列号,序列号由RequestQueue中AtomicInteger类,我们调用add方法时生成并绑定在request中,AtomicInteger的incrementAndGet方法可以生成单调递增的序列号。

/**
* Gets a sequence number.
*
* 生成单调递增的序列号
*/
public int getSequenceNumber() {
return mSequenceGenerator.incrementAndGet();
}

Request有两个抽象方法,

/**
* Subclasses must implement this to parse the raw network response
* and return an appropriate response type. This method will be
* called from a worker thread. The response will not be delivered
* if you return null.
* @param response Response from the network
* @return The parsed response, or null in the case of an error
*
* 解析response
*/
abstract protected Response<T> parseNetworkResponse(NetworkResponse response);

/**
* Subclasses must implement this to perform delivery of the parsed
* response to their listeners. The given response is guaranteed to
* be non-null; responses that fail to parse are not delivered.
* @param response The parsed response returned by
* {@link #parseNetworkResponse(NetworkResponse)}
*
* 分发Response
*/
abstract protected void deliverResponse(T response);

在说之前,我找个具体子类先看看,依然还是StringRequest:

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

@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}


一目了然,deliverResponse就是负责成功回调,因为在request只定义了公共的错误回调,成功回调交由子类自己去实现,而parseNetworkResponse则负责解析NetworkResponse,每个不同的子类解析出不同的返回类型,如这里的String,值得一提的是,这个方法之所以会定义在Request中是因为Request的泛型,只有Request知道它请求想让Response返回的是什么。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息