【Android】Retrofit框架缓存处理(离线缓存等)

来源:互联网 发布:网络验证是什么 编辑:程序博客网 时间:2024/05/05 01:51

1.简述

上一篇介绍了Retrofit的基本使用,如果您还不了解请先查看Retrofit使用详解–有些相见恨晚 这篇文章;

我们在开发app的时候,有一种情况不得不处理,就是在用户断网的清空下的一些页面显示和网络请求响应等一些情况的处理,在无网络的情况下,我们可以给一个默认的友好的提示页面,像这样:

这里写图片描述

但是有时候有些需求是在无网络连接的情况下也需要显示数据,所以我们就可以通过缓存响应数据,在无网络的情况下也可以正常显示页面,Retrofit本身并没有处理缓存,我们需要自定义拦截器来实现缓存功能,在开始之前,先来了解一下web缓存Cache-Control中max-age和max-stale的含义:

这里写图片描述

  • 想了解更多点击这里.

2.实现

下面实现的效果是:有网络时第一次请求从服务器,在20后重新请求服务器,无网络时30秒内从缓存取数据,超过时间后无法获取数据,自己可根据实际需求进行设置;

  • 离线缓存:
public static Interceptor provideOfflineCacheInterceptor ()    {        return new Interceptor()        {            @Override            public Response intercept (Chain chain) throws IOException            {                Request request = chain.request();                /**                 * 未联网获取缓存数据                 */                if (!HttpNetUtil.isNetworkConnected() )                {                    //在20秒缓存有效,此处测试用,实际根据需求设置具体缓存有效时间                    CacheControl cacheControl = new CacheControl.Builder()                            .maxStale(20, TimeUnit.SECONDS )                            .build();                    request = request.newBuilder()                            .cacheControl( cacheControl )                            .build();                }                return chain.proceed( request );            }        };    }
  • 有网络时在限定时间内多次请求取缓存,超过时间重新请求:
public static Interceptor provideCacheInterceptor ()    {        return new Interceptor()        {            @Override            public Response intercept (Chain chain) throws IOException            {                Response response = chain.proceed( chain.request() );                // re-write response header to force use of cache                // 正常访问同一请求接口(多次访问同一接口),给30秒缓存,超过时间重新发送请求,否则取缓存数据                CacheControl cacheControl = new CacheControl.Builder()                        .maxAge(30, TimeUnit.SECONDS )                        .build();                return response.newBuilder()                        .header( CACHE_CONTROL, cacheControl.toString() )                        .build();            }        };    }
  • 使用:
//设置缓存目录和缓存空间大小private static Cache provideCache (){    Cache cache = null;    try    {        cache = new Cache( new File( MyApplication.mContext.getCacheDir(), "http-cache" ),                               10 * 1024 * 1024 ); // 10 MB    }    catch (Exception e)    {         Log.e("cache","Could not create Cache!");    }    return cache;}private static OkHttpClient provideOkHttpClient (){    //日志    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);    return new OkHttpClient.Builder()           .addInterceptor( interceptor )           .addInterceptor( provideOfflineCacheInterceptor() )           .addNetworkInterceptor( provideCacheInterceptor() )           .cache( provideCache() )           .build();    }
  • 有网络直接访问,断开网络,取缓存文件:

这里写图片描述

  • 查看缓存文件:

进入data/data/包名/cache/http-cache目录,可以看到

这里写图片描述

打开后缀名为.0的文件看看:

这里写图片描述

打开后缀名为.1的文件看看:

这里写图片描述

打开journal.文件看看,里面保存的是每一条reponse记录状态,包括读取,删除,写入等动作。:

这里写图片描述


——————学无止境,希望能帮到你;

参考资料以及相关优秀文章:

1.https://caster.io/episodes/retrofit-2-offline-cache/

2.Retrofit2.0+okhttp3缓存机制以及遇到的问题

3.http://www.jianshu.com/p/9c3b4ea108a7

4.okhttp缓存浅析

2 0
原创粉丝点击