@946898963
2018-05-18T04:09:31.000000Z
字数 2685
阅读 1402
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方法:
@Overridepublic 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方法:
@Overridepublic 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中的数据实体部分使用的就是本地的缓存数据。
构造方法
构造方法就是对成员变量进行赋值。