OkHttp缓存max

发布时间:2024-12-19 16:05

拍照必备手机:iPhone 12 Pro Max #生活知识# #摄影技巧# #摄影设备推荐#

一、前言

此前编译过一篇博文OKHTTP缓存max-age和max-stale详解,在里面提到过一个问题,就是max-age在request和response中设置效果是否一样,下面将会从实验测试的角度来对这个参数进行说明。

二、测试验证和说明

2.1 实验测试代码说明
OKHttp的构建部分

OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.cache(new Cache(context.getCacheDir(), CONST_10 * CONST_1024 * CONST_1024)); //设置缓存 builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); builder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); builder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); Interceptor interceptor = new NetCacheInterceptor(); //定义response中的max-age缓存信息 builder.addInterceptor(new LocalCacheInterceptor()); //设置request中的max-age缓存信息 builder.addNetworkInterceptor(interceptor); builder.addInterceptor(new LoggingInterceptor()); factory = builder.build();1234567891011

NetCacheInterceptor设置Response中的max-age

public class NetCacheInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); CacheControl cacheControl = new CacheControl.Builder() .maxAge(300, TimeUnit.SECONDS).build(); Response response = chain.proceed(request); return response.newBuilder() .removeHeader("Pragma") .removeHeader("Cache-Control") .header("Cache-Control", cacheControl.toString()) .build(); } }1234567891011121314

LocalCacheInterceptor设置Request中的max-age信息

public class LocalCacheInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); CacheControl cacheControl = new CacheControl.Builder().maxAge(60, TimeUnit.SECONDS).build(); request = request.newBuilder() .cacheControl(cacheControl) .build(); return chain.proceed(request); } }1234567891011

网络请求的代码

//每隔3秒进行一次网络请求 Observable.interval(3, TimeUnit.SECONDS).subscribe( new Action1<Long>() { @Override public void call(Long aLong) { RetrofitResearch.getInstance(this) .getTopRecommendList() .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<ComicBeanNoCountResult>() { @Override public void call(ComicBeanNoCountResult comicBeanNoCountResult) { Log.d("yansm", "message =" + comicBeanNoCountResult.message); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { Log.d("yansm", throwable.getMessage()); } }); } } } );

1234567891011121314151617181920212223242526

2.2 实验测试
2.2.1 仅在request中设置max-age
在OKHttp的构建部分中注释掉设置Response部分的代码,参考如下:

OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.cache(new Cache(context.getCacheDir(), CONST_10 * CONST_1024 * CONST_1024)); //设置缓存 builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); builder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); builder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); Interceptor interceptor = new NetCacheInterceptor(); //定义response中的max-age缓存信息 builder.addInterceptor(new LocalCacheInterceptor()); //设置request中的max-age缓存信息 // builder.addNetworkInterceptor(interceptor); builder.addInterceptor(new LoggingInterceptor()); factory = builder.build();1234567891011

测试结果
通过抓包可以看出,每隔3秒APP依旧会发送一次网络请求
这里写图片描述
但是在Request设置的代码中定义的是60秒(参见上述代码中的设置),在APP私有目录下查看是否有缓存文件生成,结果cache目录下并没有缓存文件生成
这里写图片描述
结论:如果单单只在Request请求中设置max-age时间,max-age时间是没有生效的,并且没有生成缓存文件。
2.2.2 仅在Response中设置缓存时间max-age
在OKHttp的构建部分中注释掉设置Request部分的代码,参考如下:

OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.cache(new Cache(context.getCacheDir(), CONST_10 * CONST_1024 * CONST_1024)); //设置缓存 builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); builder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); builder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS); Interceptor interceptor = new NetCacheInterceptor(); //定义response中的max-age缓存信息 // builder.addInterceptor(new LocalCacheInterceptor()); //设置request中的max-age缓存信息 builder.addNetworkInterceptor(interceptor); builder.addInterceptor(new LoggingInterceptor()); factory = builder.build();1234567891011

另外为了方便测试,将NetCacheInterceptor.java中的时间值设置为60s。
测试结果
抓包发现,APP每隔60s才会发送一次网络请求。
这里写图片描述

在APP的私有目录下查看是否有缓存文件的生成,结果发现cache目录下生成了缓存文件。
这里写图片描述
在APP的运行日志中可以查看到,每隔3秒APP是会主动请求一次的,由于存在缓存的原因,因此最终只在每隔60s之后才会发送一个网络请求。
这里写图片描述
结论:在Response中设置网络的cache时间符合我们预期的结果,在存在缓存和缓存没有过期的情况下,网络请求直接从缓存中读取数据,在缓存过期的情况下才向后台服务器直接发送网络请求,请求成功之后再生成新的缓存。
2.2.3 同时设置Request和Response中的cache时间值
将OKHttp的构建部分中的代码还原成同时设置Request和Response的情况,只是Request的时间间隔设置成60s,Response的时间设置成300s,对APP的网络请求进行测试,测试结果如下:

图中出现403的情况是在21:02:14之后将lbs.sougu.net.cn设置为黑名单,原因见下面分析。
日志中的网络请求如下:
这里写图片描述

从日志中可以看出,每隔3秒APP也会发送网络请求,但是由于存在缓存的原因,并不会每隔3秒就直接向服务端发送网络请求。而是根据Request中设定的时间,在每隔60s之后,才向服务器发送网络请求。根据实验二中的情况,如果没有设置Request的时间值,APP直接向服务端发送网络请求的时间应该在300s之后。另外在测试120s之后,也就是APP直接向服务器发送两次请求之后,将测试的url(lbs.sougu.net.cn)在抓包工具上设置成黑名单,结果发现APP在180s进行第三次请求报错之后,APP会定时向网络直接每隔3s请求一次。

三、实验结论

以下是本次实验的总结:
1、在Response中设置max-age的时间信息,可以在APP端生成缓存文件,在缓存不过期的情况下,APP不会直接向服务器请求数据,在缓存过期的情况下,APP客户端会向服务器直接请求生成新的缓存。
2、如果是仅仅设置Request中的max-age时间,是不会生成缓存文件,并且没有缓存是否过期的情况,都是直接向后台服务器直接请求数据。
3、如果同时设置了Response和Request中的max-age 缓存时间,如果Request中的max-age时间小于Response中的max-age时间,APP会根据Request中max-age时间周期去直接进行网络请求,如果碰到断网或者网络请求不通的情况,即使缓存还在有效期内(Response中设置的max-age时间足够大),在Request设置的max-age过期之后,APP也会直接去进行网络请求。
因此可以考虑在APP的设计中一个和好的网络缓存场景,用Response的max-age控制缓存的时间,用Request中max-age控制刷新的时间和机制。

网址:OkHttp缓存max https://www.yuejiaxmz.com/news/view/519225

相关内容

使用OkHttp
Android网络优化:提升用户体验的七大策略
重建Windows图标缓存的几种方法
MAX露营生活节:MAX户外海坨露营空间揭幕
自驾出行好帮手还得看AION S MAX
iPhone 14 Pro Max省电技巧
智能辅助驾驶安全,科技助力品质舒享 奕炫MAX科技力MAX
哈弗枭龙MAX购车手册,首推四驱领航版
塞那sanag A11S Pro Max气传导耳机,运动+音乐=必选
压力测试:看你存在多大压力?

随便看看