当我们发送一个网络请求时,首先得从缓存中查询一遍,看是否存在符合的请求结果,否则的话从网络中获取请求结果,同时存入缓存中,这样不管是网络请求还是缓存获取,最终都得将结果封装下然后分发出来,这就用到Response这个类,本篇我们继续分析返回结果Response相关内容。
Response
public class Response<T> {
//成功请求后的监听结果
public interface Listener<T> {
void onResponse(T response);
}
//失败后的响应
public interface ErrorListener {
void onErrorResponse(VolleyError error);
}
//返回一个成功的响应,包含解析结果
public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {
return new Response<T>(result, cacheEntry);
}
//返回一个失败的响应
public static <T> Response<T> error(VolleyError error) {
return new Response<T>(error);
}
/** Parsed response, or null in the case of error. */
public final T result;
//响应结果的缓存
public final Cache.Entry cacheEntry;
/** Detailed error information if <code>errorCode != OK</code>. */
public final VolleyError error;
/** True if this response was a soft-expired one and a second one MAY be coming. */
public boolean intermediate = false;
//响应是否成功
public boolean isSuccess() {
return error == null;
}
private Response(T result, Cache.Entry cacheEntry) {
this.result = result;
this.cacheEntry = cacheEntry;
this.error = null;
}
private Response(VolleyError error) {
this.result = null;
this.cacheEntry = null;
this.error = error;
}
}
当然从上面我们看不出来什么内容,只能通过其他的进行研究了,首先我们来看下网络响应的类。
NetworkResponse
首先我们了解一下它的变量
//http返回状态吗
public final int statusCode;
//原始数据,也就是网络请求返回的数据
public final byte[] data;
//响应头部信息
public final Map<String, String> headers;
/** All response headers. Must not be mutated directly. */
public final List<Header> allHeaders;
//如果返回304code话表示内容没有修改过,返回TRUE
public final boolean notModified;
//网络请求时间
public final long networkTimeMs;
剩下来的就是NetworkResponse构造方法,没什么好说的,为什么又要有这个类呢?我们进行网络请求后,返回的响应结果是HttpResponse类,这个类是原生的类,扩展性和通用性不是很强,所以在BasicNetwork类中通过HttpResponse返回的结果又封装成了NetworkResponse。
return new NetworkResponse(statusCode, responseContents, false,
SystemClock.elapsedRealtime() - requestStart, responseHeaders);
在BasicNetwork中有段代码:
// Some responses such as 204s do not have content. We must check.
InputStream inputStream = httpResponse.getContent();
if (inputStream != null) {
responseContents =
inputStreamToBytes(inputStream, httpResponse.getContentLength());
} else {
// Add 0 byte response as a way of honestly representing a
// no-content request.
responseContents = new byte[0];
}
它将请求的返回结果保存到byte[]数组中去了,所以当返回的结果很大很大时就有可能发送OOM的问题,这也是为什么不能下载大文件的原因,因为它是保存在内存中的。
生成了NetworkResponse之后,在NetworkDispatcher中又将NetworkResponse转化成了Response
// Parse the response here on the worker thread.
Response<?> response = request.parseNetworkResponse(networkResponse);
这样就统一了,不管是什么请求,JsonArrayRequest、JsonObjectRequest或者StringRequest等都将转为Response,具体如何转的,得看各自的请求如何实现了。
既然存在网络请求响应类NetworkResponse,为什么不存在缓存请求响应CacheResponse呢?看CacheDispatcher中的源码可以看到
Response<?> response = request.parseNetworkResponse(
new NetworkResponse(entry.data, entry.responseHeaders));
缓存调度线程中也用到了NetworkResponse,不过应该用到的是NetworkResponse中的缓存数据,所以就不需要设计CacheResponse了。其中的Entry.data表示缓存数据。
/** The data returned from cache. */
public byte[] data;
到这里的话Response主要是对网络请求成功和失败的回调,而NetworkResponse则是一个封装了响应数据的实体。