@946898963
2018-05-18T11:29:43.000000Z
字数 3337
阅读 1165
Android控件跟框架
Android源码分析
HttpHeaderParser是Volley中的一个解析用的工具类,主要就是两个方法:parseCharset方法和parseCacheHeaders方法。
parseCharset方法的作用就是从“content-type”响应首部中解析出编码方式“charset”,如果解析不出来的话,就返回默认的编码方式“ISO-8859-1”。
parseCharset方法源码如下:
public static String parseCharset(Map<String, String> headers, String defaultCharset) {
String contentType = headers.get(HTTP.CONTENT_TYPE);
if (contentType != null) {
String[] params = contentType.split(";");
for (int i = 1; i < params.length; i++) {
String[] pair = params[i].trim().split("=");
if (pair.length == 2) {
if (pair[0].equals("charset")) {
return pair[1];
}
}
}
}
return defaultCharset;
}
public static String parseCharset(Map<String, String> headers) {
return parseCharset(headers, HTTP.DEFAULT_CONTENT_CHARSET);
}
parseCacheHeaders作用就是根据服务器返回的各种响应首部,构建一个Cache.Entry对象供我们使用。
parseCacheHeaders的源码如下所示:
public static Cache.Entry parseCacheHeaders(NetworkResponse response) {
long now = System.currentTimeMillis();
Map<String, String> headers = response.headers;
long serverDate = 0;
long lastModified = 0;
long serverExpires = 0;
long softExpire = 0;
long finalExpire = 0;
long maxAge = 0;
long staleWhileRevalidate = 0;
boolean hasCacheControl = false;
boolean mustRevalidate = false;
String serverEtag = null;
String headerValue;
headerValue = headers.get("Date");
if (headerValue != null) {
serverDate = parseDateAsEpoch(headerValue);
}
headerValue = headers.get("Cache-Control");
if (headerValue != null) {
hasCacheControl = true;
String[] tokens = headerValue.split(",");
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i].trim();
if (token.equals("no-cache") || token.equals("no-store")) {
return null;
} else if (token.startsWith("max-age=")) {
try {
maxAge = Long.parseLong(token.substring(8));
} catch (Exception e) {
}
} else if (token.startsWith("stale-while-revalidate=")) {
try {
staleWhileRevalidate = Long.parseLong(token.substring(23));
} catch (Exception e) {
}
} else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) {
mustRevalidate = true;
}
}
}
headerValue = headers.get("Expires");
if (headerValue != null) {
serverExpires = parseDateAsEpoch(headerValue);
}
headerValue = headers.get("Last-Modified");
if (headerValue != null) {
lastModified = parseDateAsEpoch(headerValue);
}
serverEtag = headers.get("ETag");
if (hasCacheControl) {
softExpire = now + maxAge * 1000;
finalExpire = mustRevalidate
? softExpire
: softExpire + staleWhileRevalidate * 1000;
} else if (serverDate > 0 && serverExpires >= serverDate) {
softExpire = now + (serverExpires - serverDate);
finalExpire = softExpire;
}
Cache.Entry entry = new Cache.Entry();
entry.data = response.data;
entry.etag = serverEtag;
entry.softTtl = softExpire;
entry.ttl = finalExpire;
entry.serverDate = serverDate;
entry.lastModified = lastModified;
entry.responseHeaders = headers;
return entry;
}
public static long parseDateAsEpoch(String dateStr) {
try {
// Parse date in RFC1123 format if this header contains one
return DateUtils.parseDate(dateStr).getTime();
} catch (DateParseException e) {
// Date in invalid format, fallback to 0
return 0;
}
}
根据Date首部,解析出serverDate,也就是服务器响应的日期。
headerValue = headers.get("Date");
if (headerValue != null) {
serverDate = parseDateAsEpoch(headerValue);
}
根据Expires首部,解析出serverExpires,也就是缓存数据的过期时间。
headerValue = headers.get("Expires");
if (headerValue != null) {
serverExpires = parseDateAsEpoch(headerValue);
}
根据Last-Modified首部,解析出lastModified,也就是服务器端返回的数据的最后修改日期。在Volley中当缓存数据过期的时候,会用到这个值发起条件请求。
headerValue = headers.get("Last-Modified");
if (headerValue != null) {
lastModified = parseDateAsEpoch(headerValue);
}
获取数据的ETag值,ETag值相当于数据的身份证,ETag值不同,说明数据不同。在Volley中当缓存数据过期的时候,会用到这个值发起条件请求。
serverEtag = headers.get("ETag");