美文网首页
Android webview默认缓存策略

Android webview默认缓存策略

作者: choha | 来源:发表于2020-02-06 23:21 被阅读0次

​一、背景

今天测试反馈,前端更新了H5的内容,但是客户端通过webview的方式打开后,发现内容没有更新,使用charles抓包,发现客户端访问访问时,连请求都没法发出。于是测试的妹子在企业微信中@我,看到消息有点懵,记得去年就排查过webview的缓存方式,怪没有记录,今天决定把问题重新记录一下。

二、webview的缓存方式

先上代码:

WebSettings settings = webView.getSettings();// 开启 DOM storage API 功能settings.setDomStorageEnabled(true);// 开启 DB storage API 功能settings.setDatabaseEnabled(true);// 开启 AppCacheEnablesettings.setAppCacheEnabled(true);

// 设置缓存模式,非常重要,决定了webview缓存资源的方式settings.setCacheMode(WebSettings.LOAD_DEFAULT);

 我们重点关注setCacheMode方法缓存模式,系统提供了5种缓存模式,其中一种已经LOAD_CACHE_NORMAL在新版本中废弃:

LOAD_CACHE_ONLY: 不发网络请求资源,只读取缓存。

LOAD_DEFAULT: 根据cache-control或者Last-Modified决定是否从网络上取数据。默认采用该方案

LOAD_CACHE_NORMAL: 新版本已经废弃,同LOAD_DEFAULT

LOAD_NO_CACHE: 不使用缓存,只从网络获取数据。

LOAD_CACHE_ELSE_NETWORK:只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。本地没有缓存时才从网络上获取。

大家都知道,webview是一个浏览器,且在4.4以下版本,都是采用WebKit作为内核,4.4以上采用Chrome作为内核。既然是浏览器,且又是缓存,那我们就有必要引入Http协议中的缓存,因为浏览器是对Http协议最基本的执行者,且浏览器的缓存原理,都是对Http协议的缓存做了基本且标准的支持(可能浏览器有扩展,但是都兼容Http基础协议)

三、HTTP协议缓存

我们这里只介绍几个常用的缓存header,详细的大家可以度娘Http协议相关。

Http协议常用的缓存header有:

Cache-Control:Cache-Control是非常最重要的规则,主要用于控制网页缓存。比如当Cache-Control:max-age=30时,在表示资源正确加载后,30s内重新请求,不在重新发网络请求,直接使用本地资源。cache-control可以配置很多规则,这里介绍几种常用的:

【max-age = xx】:在客户端缓存xx秒,过了xx秒后,重新请求资源,但是这个另外一个Etag或last-modified有关系,如果服务端跟进Etag判断文件没有修改,则返回304,这是还是使用缓存,如果返回200,则说明资源跟新了,浏览器正常从网络加载资源

【s-maxage = xx】:作用同max-age,但是会覆盖max-age,不过他只有在代理服务器中生效

【no-store】:不缓存任何资源

【no-cache】:资源会缓存,表示必须先与服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续对同一网址的请求

Expires:具体时间,例如Expires:Tue,25 Sep 2018 07:17:34 GMT, 这表示这个文件的过期时间是格林尼治时间2018年9月25日7点17分。因为我是北京时间2018年8月26日15点请求的, 所以可以看出也是差不多一个月有效期。在这个时间之前浏览器都不会再次发出请求去获取这个文件。Expires是HTTP/1.0中的字段,如果客户端和服务器时间不同步会导致缓存出现问题,因此才有了上面的Cache-Control。当它们同时出现时,Cache-Control优先级更高。

Etag:文件的一个标识,可以理解为MD5

Last-Modified:文件最后修改时间。

总结:浏览器就是跟进上述缓存逻辑,对资源进行缓存,当然了,缓存业务不仅仅这么简单,还是非常复杂的,有兴趣的可以查看HTTP协议和浏览器内核。

四、解决我遇到的问题

问题现象】:服务器的H5内容更新了,但是客户端却更新不到,且没有发请求。

问题原因猜想】:猜想android 系统的Webview做了缓存策略,导致在缓存有效期,不发请求。

既然我们已经猜想了问题原因,那就需要顺着这个思路排查该H5的缓存策略配置是什么:

这是抓包看到请求Http response的Header内置,发现只有ETag和Last-Modified,并没有配置Cache-Control,那问题来了,如果没有配置Cache-Control,那么浏览器的缓存策略是什么呢?通过一番折腾,终于找到了浏览器默认的缓存策略,这个缓存策略叫做:启发式算法,原理是:

通过采用请求响应头中的Date减轻Last-Modified的值的10%作为缓存时间,即在这10%的时间内不发请求。直接使用缓存资源。

通过验证,发现webview的默认缓存策略,确实如此。我们的问题页定位到了。既然定位了,就好解决。

五、解决方案

1、服务端添加cache-control 的方式,这里我们配置的是max-age = 24*60*60(一天),需跟进自己的业务处理。

2、也可以配置为no-cache,但是可能增加服务端的请求量,需要跟进自己的业务更新频率配置。

相关文章

  • Android webview默认缓存策略

    ​一、背景 今天测试反馈,前端更新了H5的内容,但是客户端通过webview的方式打开后,发现内容没有更新,使用c...

  • 关于Webview缓存和提速

    默认情况下的Webview缓存策略: 1、如果返回头中有Cache-Control及Last-Modified:缓...

  • 实践缓存策略

    NSURLRequestUseProtocolCachePolicy 有缓存就默认优先利用缓存,默认缓存策略。具...

  • 2018-03-11

    WebView缓存 Android WebView缓存可以分为页面缓存和数据缓存页面缓存是指加载一个网页时htm...

  • webView加载图片不显示问题

    webView 加载图片 android webview 从Lollipop(5.0)开始webview默认不允许...

  • Gradle 缓存目录结构 缓存策略

    [TOC] gradle 缓存策略 Gradle 的缓存策略中,对于 SNAPSHOT 版本默认的缓存周期是 24...

  • NSURLRequestCachePolicy 缓存策略

    1> NSURLRequestUseProtocolCachePolicy = 0, 默认的缓存策略, 如果缓存不...

  • NSURLRequest

    NSURLRequest 缓存策略 NSURLRequestUseProtocolCachePolicy=0 默认...

  • gradle缓存

    gradle缓存策略 Gradle 的缓存策略中,对于 SNAPSHOT 版本默认的缓存周期是 24 小时,也就是...

  • Swift Tip4

    1、iOS 开发textView不能从顶部显示: 2.WKWebView清除缓存: 3.webView设置缓存策略...

网友评论

      本文标题:Android webview默认缓存策略

      本文链接:https://www.haomeiwen.com/subject/tgyflttx.html