@946898963
2018-05-18T12:09:31.000000Z
字数 2685
阅读 1117
Android控件跟框架
Android源码分析
BasicNetwork使用HttpStack执行网络请求,成功后返回一个NetworkResponse,NetworkResponse只是一个简单的记录状态码,body,响应头,服务端是否返回304并且缓存过,执行网络请求时间的类。
NetworkResponse源码如下所示:
public class NetworkResponse {
public final int statusCode;
public final byte[] data;
public final Map<String, String> headers;
public final boolean notModified;
public final long networkTimeMs;
public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
boolean notModified, long networkTimeMs) {
this.statusCode = statusCode;
this.data = data;
this.headers = headers;
this.notModified = notModified;
this.networkTimeMs = networkTimeMs;
}
public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
boolean notModified) {
this(statusCode, data, headers, notModified, 0);
}
public NetworkResponse(byte[] data) {
this(HttpStatus.SC_OK, data, Collections.<String, String>emptyMap(), false, 0);
}
public NetworkResponse(byte[] data, Map<String, String> headers) {
this(HttpStatus.SC_OK, data, headers, false, 0);
}
}
成员变量
statusCode 响应的状态码
data 响应数据,也就是响应实体
headers 响应首部信息,key为相应首部,value为响应首部的值
networkTimeMs 从发起响应,到数据返回的这段时间
notModified 如果服务器端的数据没有发生修改并且本地缓存存在,为true
这里重点介绍下,notModified的值什么时候为true。当我们的Request允许使用缓存的时候,会先将Request放入到缓存请求队列中。缓存线程会从缓存请求队列中取出Request,然后去本地查找缓存,如果查找到缓存,但是缓存过期的话,会将本地的缓存数据(首部数据和实体数据)添加到Request中,然后将Request放入请求队列中,交由请求线程处理。
CacheDispatcher的run方法:
@Override
public void run() {
....
while (true) {
try {
....
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
request.addMarker("cache-miss");
// Cache miss; send off to the network dispatcher.
mNetworkQueue.put(request);
continue;
}
if (entry.isExpired()) {
request.addMarker("cache-hit-expired");
request.setCacheEntry(entry);
mNetworkQueue.put(request);
continue;
}
....
}
}
请求线程会从请求队列中取出Request,在发起请求之前,会检查Request中是否带有缓存数据(首部数据和实体数据),如果有的话会在设置请求首部的map中添加"If-None-Match"首部和"If-Modified-Since"首部,这两个首部是用来发起条件请求的,这两个首部的值分别为缓存数据中的etag和lastModified的值。
BasicNetwork的performRequest方法:
@Override
public NetworkResponse performRequest(Request<?> request) throws VolleyError {
long requestStart = SystemClock.elapsedRealtime();
while (true) {
....
Map<String, String> headers = new HashMap<String, String>();
addCacheHeaders(headers, request.getCacheEntry());
httpResponse = mHttpStack.performRequest(request, headers);
....
}
}
private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) {
if (entry == null) {
return;
}
if (entry.etag != null) {
headers.put("If-None-Match", entry.etag);
}
if (entry.lastModified > 0) {
Date refTime = new Date(entry.lastModified);
headers.put("If-Modified-Since", DateUtils.formatDate(refTime));
}
}
最终包含在请求首部的map中的首部数据,会被设置到HttpUrlConnection中去,这样发起的请求就是条件请求了。
当发起条件请求的时候,如果服务器端没有符合条件的数据(在Volley中就是数据在某个时间点后并没有发生修改),这个时候会返回304状态码,这个时候构建NetworkResponse的时候,传入的notModified的值为true,这时候NetworkResponse中的数据实体部分使用的就是本地的缓存数据。
构造方法
构造方法就是对成员变量进行赋值。