从Okhttp3源码解析之一了解到,使用OKHTTP执行一个http请求需要四步
一、接下来分析一下Request:
public final class Request {
final HttpUrl url;//请求地址
final String method;//请求模式post、get……等
final Headers headers;//请求头
final @Nullable RequestBody body;//请求正文
final Map<Class<?>, Object> tags;//请求标志,如取消请求时需要使用到
private volatile @Nullable CacheControl cacheControl; // 缓存控制
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tags = Util.immutableMap(builder.tags);
}
Request类有个CacheControl方法
public Builder cacheControl(CacheControl cacheControl) {
String value = cacheControl.toString();
if (value.isEmpty()) return removeHeader("Cache-Control");
return header("Cache-Control", value);
}
原来是通过header的Cache-Control来控制缓存。
二、进一步了解CacheControl
public final class CacheControl {
//没有缓存
public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
//只接收缓存数据,如果响应在缓存中不可用或需要服务器验证,则调用失败且响应504状态码
public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
//没有缓存
private final boolean noCache;
//所有内容都不会被缓存到缓存或 Internet 临时文件中
private final boolean noStore;
//设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。
private final int maxAgeSeconds;
//覆盖max-age 或者 Expires 头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略。
private final int sMaxAgeSeconds;
//内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存)
private final boolean isPrivate;
//所有内容都将被缓存(客户端和代理服务器都可缓存)
private final boolean isPublic;
//缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
private final boolean mustRevalidate;
//表明客户端愿意接收一个已经过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过时时间。
private final int maxStaleSeconds;
//表示客户端希望在指定的时间内获取最新的响应。
private final int minFreshSeconds;
//表明如果缓存存在,只使用缓存,无论原始服务器数据是否有更新。
private final boolean onlyIfCached;
//不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。
private final boolean noTransform;
//表示响应正文不会随时间而改变。资源(如果未过期)在服务器上不发生改变,因此客户端不应发送重新验证请求头(例如If-None-Match或If-Modified-Since)来检查更新,即使用户显式地刷新页面
private final boolean immutable;
***省略代码
//对应头部信息
private String headerValue() {
StringBuilder result = new StringBuilder();
if (noCache) result.append("no-cache, ");
if (noStore) result.append("no-store, ");
if (maxAgeSeconds != -1) result.append("max-age=").append(maxAgeSeconds).append(", ");
if (sMaxAgeSeconds != -1) result.append("s-maxage=").append(sMaxAgeSeconds).append(", ");
if (isPrivate) result.append("private, ");
if (isPublic) result.append("public, ");
if (mustRevalidate) result.append("must-revalidate, ");
if (maxStaleSeconds != -1) result.append("max-stale=").append(maxStaleSeconds).append(", ");
if (minFreshSeconds != -1) result.append("min-fresh=").append(minFreshSeconds).append(", ");
if (onlyIfCached) result.append("only-if-cached, ");
if (noTransform) result.append("no-transform, ");
if (immutable) result.append("immutable, ");
if (result.length() == 0) return "";
result.delete(result.length() - 2, result.length());
return result.toString();
}
***省略代码
}
三、缓存策略CacheStrategy
public final class CacheStrategy {
/** The request to send on the network, or null if this call doesn't use the network. */
public final @Nullable Request networkRequest;
/** The cached response to return or validate; or null if this call doesn't use a cache. */
public final @Nullable Response cacheResponse;
CacheStrategy(Request networkRequest, Response cacheResponse) {
this.networkRequest = networkRequest;
this.cacheResponse = cacheResponse;
}
/** Returns true if {@code response} can be stored to later serve another request. */
public static boolean isCacheable(Response response, Request request) {
// Always go to network for uncacheable response codes (RFC 7231 section 6.1),
// This implementation doesn't support caching partial content.
switch (response.code()) {
case HTTP_OK:
case HTTP_NOT_AUTHORITATIVE:
case HTTP_NO_CONTENT:
case HTTP_MULT_CHOICE:
case HTTP_MOVED_PERM:
case HTTP_NOT_FOUND:
case HTTP_BAD_METHOD:
case HTTP_GONE:
case HTTP_REQ_TOO_LONG:
case HTTP_NOT_IMPLEMENTED:
case StatusLine.HTTP_PERM_REDIRECT:
// These codes can be cached unless headers forbid it.
break;
case HTTP_MOVED_TEMP:
case StatusLine.HTTP_TEMP_REDIRECT:
// These codes can only be cached with the right response headers.
// http://tools.ietf.org/html/rfc7234#section-3
// s-maxage is not checked because OkHttp is a private cache that should ignore s-maxage.
if (response.header("Expires") != null
|| response.cacheControl().maxAgeSeconds() != -1
|| response.cacheControl().isPublic()
|| response.cacheControl().isPrivate()) {
break;
}
// Fall-through.
default:
// All other codes cannot be cached.
return false;
}
// A 'no-store' directive on request or response prevents the response from being cached.
return !response.cacheControl().noStore() && !request.cacheControl().noStore();
}
***省略代码
}
主要是给定一个请求和缓存的响应,这将决定是使用网络、缓存还是两者都有。
详细的缓存策略CacheStrategy解析