okhttp添加本地缓存(支持get post)
来源:互联网 发布:tensorflow函数 编辑:程序博客网 时间:2024/05/29 13:47
要实现一个okhttp的缓存策略,就是对应某些个接口缓存,第一反应就是拦截器,拦截器是okhttp中的精华所在,大体逻辑:
1.拿到文件的最后修改时间和当前时间对比,大于30分钟,缓存失效,重新请求并缓存数据
2.对比时间,小于30分钟,直接从缓存读取,重新构造response在拦截器方法中返回
上代码:
public class CacheInterceptor implements Interceptor { private List<String> cacheRouters = new ArrayList<String>() { { this.add("/upgrade/appupdate"); } }; private static final long CACHE_TIME = 60*30*1000; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String path = request.url().url().getPath(); if (!cacheRouters.contains(path)) return chain.proceed(request); //需要拦截的路由 File file = createCacheFile(path); long lastModified = file.lastModified(); long nowTime = System.currentTimeMillis(); Response response = null; if (nowTime - lastModified > CACHE_TIME || file.length() == 0) { //缓存文件过期(或者第一次创建内容是空的),去请求并且缓存下来 response = reqAndCache(chain.proceed(request), file); } else { //缓存文件没过期,读取缓存,构建response对象 response = getCache(request,file); } return response; }
接着是重新请求的方法:
private Response reqAndCache(Response response,File file){ String body = null; try { body = response.body().string(); JSONObject object = new JSONObject(body); int code = object.optInt("code", 0); if(code == 200) write(file,body); } catch (Exception e) { e.printStackTrace(); } return response.newBuilder().body(ResponseBody.create(response.body().contentType(),body)).build(); }这里的response.newBuilder()是因为 调用了一次response.body().string()之后和服务器的链接流就关闭了,把这个response给用户是无效的
走缓存并构建response的方法:
private Response getCache(Request request, File file) { MediaType json = MediaType.parse("text/html; charset=utf-8"); return new Response.Builder(). body(ResponseBody.create(json,readFile(file).getBytes())) .request(request) .protocol(Protocol.HTTP_1_1) .code(200) .message("OK") .build(); }这里之所以重新new一个 response,是因为调用chain.process(request)是需要走网络返回一个socket流,对于没有网络的缓存就不支持了
对于缓存文件的读写我是用的okio的api okio的读写都有一个环形链表的buffer给于支持,效率非常之高
贴上整个拦截器的代码:
public class CacheInterceptor implements Interceptor { private List<String> cacheRouters = new ArrayList<String>() { { this.add("/upgrade/appupdate"); } }; private static final long CACHE_TIME = 60*30*1000; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String path = request.url().url().getPath(); if (!cacheRouters.contains(path)) return chain.proceed(request); //需要拦截的路由 File file = createCacheFile(path); long lastModified = file.lastModified(); long nowTime = System.currentTimeMillis(); Response response = null; if (nowTime - lastModified > CACHE_TIME || file.length() == 0) { //缓存文件过期(或者第一次创建内容是空的),去请求并且缓存下来 response = reqAndCache(chain.proceed(request), file); } else { //缓存文件没过期,读取缓存,构建response对象 response = getCache(request,file); } return response; } private Response getCache(Request request, File file) { MediaType json = MediaType.parse("text/html; charset=utf-8"); return new Response.Builder(). body(ResponseBody.create(json,readFile(file).getBytes())) .request(request) .protocol(Protocol.HTTP_1_1) .code(200) .message("OK") .build(); } private Response reqAndCache(Response response,File file){ String body = null; try { body = response.body().string(); JSONObject object = new JSONObject(body); int code = object.optInt("code", 0); if(code == 200) write(file,body); } catch (Exception e) { e.printStackTrace(); } return response.newBuilder().body(ResponseBody.create(response.body().contentType(),body)).build(); } private File createCacheFile(String path) { File file = new File(getDiskCacheDir("stockcode"), MD5Util.myMd5(path) + ".json"); if (!file.exists()) try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } return file; } private File getDiskCacheDir(String uniqueName) { String cachePath = MyApplication.CONTEXT.getExternalCacheDir().getPath(); File file = new File(cachePath + File.separator + uniqueName); if (!file.exists()) file.mkdirs(); Logs.e("size",file.length()); return file; } public String readFile(File file){ Source source; BufferedSource bufferedSource = null; String read = ""; try { source = Okio.source(file); bufferedSource = Okio.buffer(source); read = bufferedSource.readUtf8(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != bufferedSource) { bufferedSource.close(); } } catch (IOException e) { e.printStackTrace(); } } return read; } private void write(File file,String content){ Sink sink; BufferedSink bufferedSink = null; try { sink = Okio.sink(file); bufferedSink = Okio.buffer(sink); bufferedSink.writeUtf8(content); bufferedSink.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != bufferedSink) { bufferedSink.close(); } } catch (IOException e) { e.printStackTrace(); } } }}
阅读全文
1 0
- okhttp添加本地缓存(支持get post)
- OkHttp(1):GET和POST
- OkHttp的使用--GET/POST(异步)
- OKHttp网络请求(get / post)
- okHttp post&get请求
- okhttp get post请求
- okhttp get+缓存
- OkHttp get post 简单用法
- OkHttp get和post封装
- OkHttp的Get和Post
- okhttp GET请求 post请求
- okhttp get post 使用源代码
- OkHttp Get请求/Post请求
- Okhttp 异步get post 请求
- retrofit2.0中使用okHTTP post get put 过滤请求内容或添加内容
- okhttp 网络请求添加请求头,get和post请求,表单提交 ,二进制流
- Android okHttp 实战(一):okHttp网络请求之Get/Post请求
- OkHttp GET 和 POST 的使用
- iOS计算字符的长度
- spring源码学习之路---深度分析IOC容器初始化过程(四)
- [刷题]ACM ICPC 2015合肥网络赛
- Kay and Snowflake CodeForces
- pandas入门——多表操作
- okhttp添加本地缓存(支持get post)
- Python-25 with
- python笔记之unittest
- BZOJ 4627回转寿司(值域线段树)
- 我的spring 上
- 设计作品的好坏怎么看
- java多线程----synchronized方法锁能否锁住对象呢?
- php flush类输出缓冲剖析
- 连接IBM MQ原因码报2035的错误解决方法