Android的HTTP扩展包OkHttp中的缓存功能使用方法解析
OkHttp可以对HTTP响应的内容在磁盘上进行缓存。在进行HTTP请求时,如果该请求的响应已经被缓存而且没有过期,OkHttp会直接使用缓存中的响应内容,而不需要真正的发出HTTP请求到远程服务器。在创建缓存时需要指定一个磁盘目录和缓存的大小。在代码清单8中,创建出Cache对象之后,通过OkHttpClient的setCache进行设置。通过Response对象的cacheResponse和networkResponse方法可以得到缓存的响应和从实际的HTTP请求得到的响应。如果该请求的响应来自实际的网络请求,则cacheResponse方法的返回值为null;如果响应来自缓存,则networkResponse的返回值为null。OkHttp在进行缓存时会遵循HTTP协议的要求,因此可以通过标准的HTTP头Cache-Control来控制响应的缓存时间。
设置响应缓存的示例
publicclassCacheResponse{ publicstaticvoidmain(String[]args)throwsIOException{ intcacheSize=100*1024*1024; FilecacheDirectory=Files.createTempDirectory("cache").toFile(); Cachecache=newCache(cacheDirectory,cacheSize); OkHttpClientclient=newOkHttpClient(); client.setCache(cache); Requestrequest=newRequest.Builder() .url("http://www.baidu.com") .build(); Responseresponse=client.newCall(request).execute(); if(!response.isSuccessful()){ thrownewIOException("服务器端错误:"+response); } System.out.println(response.cacheResponse()); System.out.println(response.networkResponse()); } }
Cache-Control
Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令有下几种:
Public指示响应可被任何缓存区缓存。
Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
(1)no-cache指示请求或响应消息不能缓存
(2)no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
(3)max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
(4)min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
(5)max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
CacheControl类详细介绍:
1.)常用的函数:如下代码,里面已经加了注释就不一一解释了,每个函数都是对应一个缓存指令设置
finalCacheControl.Builderbuilder=newCacheControl.Builder(); builder.noCache();//不使用缓存,全部走网络 builder.noStore();//不使用缓存,也不存储缓存 builder.onlyIfCached();//只使用缓存 builder.noTransform();//禁止转码 builder.maxAge(10,TimeUnit.MILLISECONDS);//指示客户机可以接收生存期不大于指定时间的响应。 builder.maxStale(10,TimeUnit.SECONDS);//指示客户机可以接收超出超时期间的响应消息 builder.minFresh(10,TimeUnit.SECONDS);//指示客户机可以接收响应时间小于当前时间加上指定时间的响应。 CacheControlcache=builder.build();//cacheControl
2.)两个CacheControl常量介绍:
CacheControl.FORCE_CACHE;//仅仅使用缓存 CacheControl.FORCE_NETWORK;//仅仅使用网络
举例,我们设置一个有效期为10秒的CacheControl
finalCacheControl.Builderbuilder=newCacheControl.Builder(); builder.maxAge(10,TimeUnit.MILLISECONDS); CacheControlcache=builder.build();
3.)请求时如何使用
finalCacheControl.Builderbuilder=newCacheControl.Builder(); builder.maxAge(10,TimeUnit.MILLISECONDS); CacheControlcache=builder.build(); finalRequestrequest=newRequest.Builder().cacheControl(cache).url(requestUrl).build(); finalCallcall=mOkHttpClient.newCall(request);// call.enqueue(newCallback(){ @Override publicvoidonFailure(Callcall,IOExceptione){ failedCallBack("访问失败",callBack); Log.e(TAG,e.toString()); } @Override publicvoidonResponse(Callcall,Responseresponse)throwsIOException{ if(response.isSuccessful()){ Stringstring=response.body().string(); Log.e(TAG,"response----->"+string); successCallBack((T)string,callBack); }else{ failedCallBack("服务器错误",callBack); } } }); returncall; }catch(Exceptione){ Log.e(TAG,e.toString()); }
以上如果cache没有过去会直接返回cache而不会发起网络请求,若过期会自动发起网络请求。注意:如果您使用FORCE_CACHE和网络的响应需求,OkHttp则会返回一个504提示,告诉你不可满足请求响应。所以我们加一个判断在没有网络的情况下使用
//判断网络是否连接 booleanconnected=NetworkUtil.isConnected(context); if(!connected){ request=request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); }