Android okhttp 获取缓存响应
Android okhttp get cache response
我不是处理 http 的专家,但我想完成的是:
如果响应在缓存中 return 如果不在缓存中 return 网络响应就这么简单。
但问题是响应代码始终是 504,但我确定它已被缓存,所以据我了解它应该 return != 504,代码在 "doGetRequest"方法。
我的 okhttp 客户端:
public class RestAsyncHttpClient {
/* Constants */
private static final String TAG = "RestAsyncHttpClient";
private static long HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
private static final String DISK_CACHE_SUBDIR = "cacheApi";
/* Properties */
private static OkHttpClient mHttpClient;
private static Cache cache;
private static RestAsyncHttpClient instance = null;
private Context context;
public static RestAsyncHttpClient getInstance() {
if (instance == null) {
instance = new RestAsyncHttpClient();
}
return instance;
}
/**
* Initialize HttpClient
*/
public void initialize(Context context) {
setContext(context);
mHttpClient = new OkHttpClient();
configureSslSocketFactory();
configureCache();
configureTimeouts();
}
private void setContext(Context context) {
this.context = context;
}
private void configureSslSocketFactory() {
mHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
}
public static void doGetRequest(String url, Callback callback) throws IOException {
Request cachedRequest = new Request.Builder()
.cacheControl(new CacheControl.Builder().onlyIfCached().build())
.url(url)
.build();
Response forceCacheResponse = mHttpClient.newCall(cachedRequest).execute();
if (forceCacheResponse.code() != 504) {
// The resource was cached! Show it.
callback.onResponse(forceCacheResponse);
} else {
Request networkRequest = new Request.Builder().url(url).build();
mHttpClient.newCall(networkRequest).enqueue(callback);
}
}
private void configureCache() {
if (cache == null)
cache = createHttpClientCache(context);
mHttpClient.setCache(cache);
}
private static Cache createHttpClientCache(Context context) {
try {
File cacheDir = context.getDir("cache_api", Context.MODE_PRIVATE);
return new Cache(cacheDir, HTTP_CACHE_SIZE);
} catch (IOException exp) {
LogHelper.error(TAG, "Couldn't create http cache because of IO problem.", exp);
return null;
}
}
private void configureTimeouts() {
mHttpClient.setConnectTimeout(10, TimeUnit.SECONDS);
mHttpClient.setWriteTimeout(35, TimeUnit.SECONDS);
mHttpClient.setReadTimeout(35, TimeUnit.SECONDS);
}
}
我的缓存正在被填充,所以当没有可用连接时它应该从缓存中读取。
来自服务器的响应 Headers:
- 连接:关闭
- Content-Type:application/json;字符集=iso-8859-1
- 日期:2015 年 3 月 23 日,星期一 11:04:44 GMT
- 服务器:Apache
- Transfer-Encoding:分块
- X-Powered-By:Servlet/2.5 JSP/2.1
请求Headers:
- 接受:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
- Accept-Encoding:gzip, deflate, sdch
- Accept-Language:pt-PT,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2
- Cache-Control:max-age=0
- 连接:keep-alive
- 主持人:不能分享:448
- User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36
(KHTML,如 Gecko)Chrome/41.0.2272.101 Safari/537.36
当你得到响应时,你需要完整地读取它,否则它不会被缓存。这是因为 OkHttp 只有在你读完它的主体时才会将响应提交给缓存。
不需要 504 的特殊情况。只需定期发出请求,它会在可能的情况下使用缓存。
我不是处理 http 的专家,但我想完成的是:
如果响应在缓存中 return 如果不在缓存中 return 网络响应就这么简单。
但问题是响应代码始终是 504,但我确定它已被缓存,所以据我了解它应该 return != 504,代码在 "doGetRequest"方法。
我的 okhttp 客户端:
public class RestAsyncHttpClient {
/* Constants */
private static final String TAG = "RestAsyncHttpClient";
private static long HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
private static final String DISK_CACHE_SUBDIR = "cacheApi";
/* Properties */
private static OkHttpClient mHttpClient;
private static Cache cache;
private static RestAsyncHttpClient instance = null;
private Context context;
public static RestAsyncHttpClient getInstance() {
if (instance == null) {
instance = new RestAsyncHttpClient();
}
return instance;
}
/**
* Initialize HttpClient
*/
public void initialize(Context context) {
setContext(context);
mHttpClient = new OkHttpClient();
configureSslSocketFactory();
configureCache();
configureTimeouts();
}
private void setContext(Context context) {
this.context = context;
}
private void configureSslSocketFactory() {
mHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
}
public static void doGetRequest(String url, Callback callback) throws IOException {
Request cachedRequest = new Request.Builder()
.cacheControl(new CacheControl.Builder().onlyIfCached().build())
.url(url)
.build();
Response forceCacheResponse = mHttpClient.newCall(cachedRequest).execute();
if (forceCacheResponse.code() != 504) {
// The resource was cached! Show it.
callback.onResponse(forceCacheResponse);
} else {
Request networkRequest = new Request.Builder().url(url).build();
mHttpClient.newCall(networkRequest).enqueue(callback);
}
}
private void configureCache() {
if (cache == null)
cache = createHttpClientCache(context);
mHttpClient.setCache(cache);
}
private static Cache createHttpClientCache(Context context) {
try {
File cacheDir = context.getDir("cache_api", Context.MODE_PRIVATE);
return new Cache(cacheDir, HTTP_CACHE_SIZE);
} catch (IOException exp) {
LogHelper.error(TAG, "Couldn't create http cache because of IO problem.", exp);
return null;
}
}
private void configureTimeouts() {
mHttpClient.setConnectTimeout(10, TimeUnit.SECONDS);
mHttpClient.setWriteTimeout(35, TimeUnit.SECONDS);
mHttpClient.setReadTimeout(35, TimeUnit.SECONDS);
}
}
我的缓存正在被填充,所以当没有可用连接时它应该从缓存中读取。
来自服务器的响应 Headers:
- 连接:关闭
- Content-Type:application/json;字符集=iso-8859-1
- 日期:2015 年 3 月 23 日,星期一 11:04:44 GMT
- 服务器:Apache
- Transfer-Encoding:分块
- X-Powered-By:Servlet/2.5 JSP/2.1
请求Headers:
- 接受:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
- Accept-Encoding:gzip, deflate, sdch
- Accept-Language:pt-PT,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2
- Cache-Control:max-age=0
- 连接:keep-alive
- 主持人:不能分享:448
- User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,如 Gecko)Chrome/41.0.2272.101 Safari/537.36
当你得到响应时,你需要完整地读取它,否则它不会被缓存。这是因为 OkHttp 只有在你读完它的主体时才会将响应提交给缓存。
不需要 504 的特殊情况。只需定期发出请求,它会在可能的情况下使用缓存。