项目作者: huburt-Hu

项目描述 :
some business inteceptors for okhttp such as custom cache
高级语言: Java
项目地址: git://github.com/huburt-Hu/Interceptors.git
创建时间: 2018-06-28T06:28:27Z
项目社区:https://github.com/huburt-Hu/Interceptors

开源协议:

下载


Interceptors

一些与业务相关的okhttp拦截器

导入

项目的build.gradle添加:

  1. allprojects {
  2. repositories {
  3. ...
  4. maven { url 'https://jitpack.io' }
  5. }
  6. }

module的build.gradle添加:

  1. dependencies {
  2. implementation 'com.github.huburt-Hu:Interceptors:v0.1.0'
  3. }

com.huburt.interceptors.CacheInterceptor

介绍

okhttp自带的CacheInterceptor只能缓存GET请求,并且需要服务端的支持(或者自定义拦截器模拟服务端支持)。
而有时候出于业务或者其他的因素,我们需要在app端控制缓存,并且可能还需要缓存post请求。
因此本人写了一个CacheInterceptor用于实现以上需求。

使用

com.huburt.interceptors.CacheInterceptor是一个抽象类,使用时可以直接使用默认实现。
首先我们向okhttp的client添加我们的CacheInterceptor的默认实现:

  1. client = new OkHttpClient.Builder()
  2. .addInterceptor(CacheInterceptor.getDefault(context))
  3. .build();

其次在需要缓存的请求上添加header:

  1. Request request = new Request.Builder()
  2. .url("http://www.baidu.com")
  3. .addHeader(CacheInterceptor.HEADER_NAME, String.valueOf(60))
  4. .build();
  1. @Headers({CacheInterceptor.HEADER_NAME + ":60"})
  2. @GET("users/{user}/repos")
  3. Call<ResponseBody> listRepos(@Path("user") String user);

header的key为CacheInterceptor.HEADER_NAME,value为缓存时间,单位是毫秒

缓存逻辑

  1. @Override
  2. public Response intercept(Chain chain) throws IOException {
  3. Request request = chain.request();
  4. //读取指定header
  5. String header = request.header(HEADER_NAME);
  6. //不为空,表示需要缓存
  7. if (!TextUtils.isEmpty(header)) {
  8. //获取缓存的key,get等请求为url,post等请求为url+requestBody 取md5
  9. String key = getCacheKey(request);
  10. //获取缓存
  11. T cache = getCache(key);
  12. //判断缓存时候可用
  13. if (checkUseful(cache)) {//缓存可用,从缓存中创建Response对象
  14. return createResponseFromCache(request, cache);
  15. } else {//缓存不可用,走网络
  16. Response response = chain.proceed(request);
  17. if (response.isSuccessful()) {//如果接口请求成功,则缓存结果
  18. int cacheTime = parseCacheTime(header);
  19. saveAsCache(key, convert(response), cacheTime);
  20. }
  21. return response;
  22. }
  23. }
  24. //没有header,表示不需要缓存,不做处理
  25. return chain.proceed(request);
  26. }

扩展

默认实现是将ResponseBody转换成String,缓存到cache磁盘。
如果不喜欢默认实现的缓存,也可以自己继承CacheInterceptor实现自己的缓存逻辑。
需要实现以下几个方法,其中T为泛型,表示缓存实体的类型:

  1. /**
  2. * @param request okhttp request
  3. * @param cache the cache from {@link CacheInterceptor#getCache} and checked useful
  4. * @return response for okhttp
  5. */
  6. protected abstract Response createResponseFromCache(Request request, T cache);
  7. /**
  8. * @param cache the cache from {@link CacheInterceptor#getCache}
  9. * @return true if the cache is useful or false
  10. */
  11. protected abstract boolean checkUseful(T cache);
  12. /**
  13. * use default cache time when the cache header set with wrong content.
  14. * you can override this method return your custom default cache time.
  15. *
  16. * @return time in minutes
  17. */
  18. public int defaultCacheTime() {
  19. return 60;
  20. }
  21. /**
  22. * get cache by key
  23. *
  24. * @param key key of cache
  25. * @return cache or null
  26. */
  27. public abstract T getCache(String key);
  28. /**
  29. * convert response to your custom cache entity
  30. *
  31. * @param response okhttp response
  32. * @return cache entity
  33. */
  34. protected abstract T convert(Response response);
  35. /**
  36. * save the cache entity
  37. *
  38. * @param key MD5 of url (if request method is post or patch ,key is url + requestBody)
  39. * @param cacheEntity custom entity
  40. * @param cacheTime cache time (minutes)
  41. */
  42. protected abstract void saveAsCache(String key, T cacheEntity, int cacheTime);
  43. /**
  44. * remove cache by key
  45. *
  46. * @param key key of cache
  47. */
  48. public abstract void removeCache(T key);
  49. /**
  50. * clear all cache of http
  51. */
  52. public abstract void clearCache();