WebApp:如何让安卓的webview缓存webapp的html、js和图片等资源

一、开发环境

客户端:安卓+webview(vuejs)

服务器端:tomcat 8.0

二、问题

使用安卓原生+web(基于webpack+vuejs)的方式开发了一个安卓应用,由于web的js文件较大,大概有400k左右,每次从app中打开该页面都要重新从服务器端下载页面的html、js和图片等静态资源,反应速度比较慢了,大概需要三四秒(如果用户网速慢的话,则需要更久),体验效果就很不好。

所以就考虑是不是可以只在第一次打开的时候下载,然后就缓存在客户端,以后只有有更新的时候才下载,但是开发人员在将安卓的webview的缓存选项设置为LOAD_DEFAULT之后,并且在html的head加上如下meta标签,但是似乎没有效果,有时候会缓存,有时候有重新下载,和预期的行为不一致。

<meta http-equiv="Cache-Control" content="max-age=604800"/>

三、分析

首先安卓的webview的缓存选项设置为LOAD_DEFAULT应该没错,这点没有太大疑问,我们就是想要 根据cache-control决定是否从网络上取数据。

然后重点就是在html中的这个Cache-Control设置,分析之后发现这其实是一个http协议范畴的内容,下图是《http 权威指南》中的描述。

所以现在要验证这个在html的cache-control meta标签是否起作用,可以从两个方面来找原因:

(1) 首先可以看看tomcat是否支持,比如他在遇到html的时候,是否会解析其中的cache-control meta设置,然后在回复的http报文头上加上Cache-Control,使用wireshark抓取的html页面响应的报文头如下,这说明tomcat默认是不支持解析html页面头上的cache-control meta标签的。



 (2) 然后就是看安卓的webview是否支持解析该meta标签了,这点在android官方的webview说明中没有招到,可能要去webkit的官方去找。

但是一篇博文上招到如下说明:

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /><meta http-equiv="Pragma" content="no-cache" /><meta http-equiv="Expires" content="0" />

但,实际情况是,这些meta只能在file:// 本地文件中使用,如果是服务器则默认被覆盖。现在目前主流的就是使用HTTP1.1协议缓存
不过我们一般都不会单独使用某一项。

所以我估计这个meta tag在android的webview中 是没有作用的。

四、解决方案

按照:使用Cache-Control和gzip提升tomcat应用性能(整理), http://qin686-163-com.iteye.com/blog/287782

在后端代码中添加了过滤器,然后回复的http报文头上就有cache-control,就可以按照设置的max-age正确缓存了。

Filter的代码:

Java代码  

  1. public class ResponseHeaderFilter implements Filter {
  2. FilterConfig fc;
  3. public void doFilter(ServletRequest req, ServletResponse res,
  4. FilterChain chain) throws IOException, ServletException {
  5. HttpServletResponse response = (HttpServletResponse) res;
  6. // set the provided HTTP response parameters
  7. for (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) {
  8. String headerName = (String) e.nextElement();
  9. response.addHeader(headerName, fc.getInitParameter(headerName));
  10. }
  11. // pass the request/response on
  12. chain.doFilter(req, response);
  13. }
  14. public void init(FilterConfig filterConfig) {
  15. this.fc = filterConfig;
  16. }
  17. public void destroy() {
  18. this.fc = null;
  19. }
  20. }

web.xml里的巧妙配置:

Xml代码  

  1. <filter>
  2. <filter-name>NoCache</filter-name>
  3. <filter-class>apis.server.common.util.ResponseHeaderFilter</filter-class>
  4. <init-param>
  5. <param-name>Cache-Control</param-name>
  6. <param-value>no-cache, must-revalidate</param-value>
  7. </init-param>
  8. </filter>
  9. <filter>
  10. <filter-name>CacheForWeek</filter-name>
  11. <filter-class>apis.server.common.util.ResponseHeaderFilter</filter-class>
  12. <init-param>
  13. <param-name>Cache-Control</param-name>
  14. <param-value>max-age=604800, public</param-value>
  15. </init-param>
  16. </filter>
  17. <filter-mapping>
  18. <filter-name>NoCache</filter-name>
  19. <url-pattern>*.do</url-pattern>
  20. </filter-mapping>
  21. <filter-mapping>
  22. <filter-name>CacheForWeek</filter-name>
  23. <url-pattern>/images/*</url-pattern>
  24. </filter-mapping>
  25. <filter-mapping>
  26. <filter-name>CacheForWeek</filter-name>
  27. <url-pattern>/img/*</url-pattern>
  28. </filter-mapping>
  29. <filter-mapping>
  30. <filter-name>CacheForWeek</filter-name>
  31. <url-pattern>/icons/*</url-pattern>
  32. </filter-mapping>
  33. <filter-mapping>
  34. <filter-name>CacheForWeek</filter-name>
  35. <url-pattern>/ext/*</url-pattern>
  36. </filter-mapping>
  37. <filter-mapping>
  38. <filter-name>CacheForWeek</filter-name>
  39. <url-pattern>*.js</url-pattern>
  40. </filter-mapping>
  41. <filter-mapping>
  42. <filter-name>CacheForWeek</filter-name>
  43. <url-pattern>*.css</url-pattern>
  44. </filter-mapping>

附录、参考资料

0)亲,你知道缓存是什么吗?https://segmentfault.com/a/1190000004486640

1)android Cache——webview的缓存处理,http://blog.csdn.net/yehui928186846/article/details/51445894

2)介绍Cache-control来详解网页的缓存问题,http://www.56gee.com/Detail/2013/07/22/8A96968D88/

3)使用Cache-Control和gzip提升tomcat应用性能(整理), http://qin686-163-com.iteye.com/blog/287782

来自为知笔记(Wiz)

时间: 2024-08-17 23:33:45

WebApp:如何让安卓的webview缓存webapp的html、js和图片等资源的相关文章

C#开发移动应用系列(2.使用WebView搭建WebApp应用)

前言 上篇文章地址:C#开发移动应用系列(1.环境搭建) 嗯..一周了 本来打算2天一更的 - - ,结果 出差了..请各位原谅.. 今天我们来讲一下使用WebView搭建WebApp应用. 说明一下为何要用WebApp的形式,因为首先..易于更新,其次学习成本又会降低一个档次 因为不需要去很深入的了解各种安卓的界面布局,我们直接全屏覆盖一个WebView就好了.(当然,实际应用中还是需要加入一部分原生控件来提高用户体验) 确定一下本篇的学习目标: 1.学会使用WebView基础功能 2.通过W

安卓高级 WebView的使用到 js交互

我们先来学习 怎么使用再到用js和安卓源生方法交互 WebView简单使用 此部分转载并做了补充 原博客 原因:比较简单不是很想在写,我只要写js交互部分 WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要处理解析,渲染网页等浏览器做的事情 setWebChromeClient:辅助WebView处理Javascript的对话框,网站图标,网站ti

webview 缓存

What is 'Context' on Android? Putting it simply: As the name suggests, it's the context of current state of the application/object. It lets newly-created objects understand what has been going on. Typically you call it to get information regarding an

处理ios webview 更新缓存本地css、js后webview缓存无法更新的问题

项目中需要使用app本地css.js,并且可以根据服务下发自动更新本地css.js.测试发现只要更新后的css或者js和更新前路径一致,webview加载的还是更新前的css.js.怀疑是webview本身缓存了css.js. 使用很多原生方法比如: [[NSURLCache sharedURLCache] removeAllCachedResponses];[[NSURLCache sharedURLCache] setDiskCapacity:0];[[NSURLCache sharedUR

Android WebView 缓存处理

加载html时,会在data/应用下生成database和cache两个文件夹:请求的url存在webviewcache.db下面,url的内容保存在webviewCache下面, Webview的两种缓存:网页数据缓存(存储打开的页面及资源),另一种则是h5转存,即appcache: 一.网页缓存 1.缓存构成 /data/data/package_name/cache/ /data/data/package_name/database/webview.db /data/data/packag

android 读取WebView缓存及清理WebView缓存

WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源).H5缓存(即appcache). 一.网页缓存 1.缓存构成 /data/data/package_name/cache/ /data/data/package_name/database/webview.db /data/data/package_name/database/webviewCache.db 在项目中经常会使用到WebView控件,当加载html页面时,会在/data/data/应用package目录下生成d

【android】WebView缓存数据收集

Android WebView 缓存 Android高手进阶教程(二十四)之---Android WebView的缓存!!! Android webView 缓存 Cache + HTML5离线功能 解决 WebView图片和JS,CSS如何将这些资源文件缓存 版权声明:本文博客原创文章.博客,未经同意,不得转载.

【安卓中的缓存策略系列】安卓缓存策略之磁盘缓存DiskLruCache

安卓中的缓存包括两种情况即内存缓存与磁盘缓存,其中内存缓存主要是使用LruCache这个类,其中内存缓存我在[安卓中的缓存策略系列]安卓缓存策略之内存缓存LruCache中已经进行过详细讲解,如看官还没看过此博客,建议看官先去看一下. 我们知道LruCache可以让我们快速的从内存中获取用户最近使用过的Bitmap,但是我们无法保证最近访问过的Bitmap都能够保存在缓存中,像类似GridView等需要大量数据填充的控件很容易就会用完整个内存缓存.另外,我们的应用可能会被类似打电话等行为而暂停导

安卓中webview读取html,同时嵌入Flex的SWF,交互

安卓中webview读取html,同时嵌入Flex的SWF,交互 安卓activity与html交互很简单,用javascript接口即可,网上一堆的例子,基本上没多大问题. 在html里面嵌入swf并与之交互就有点麻烦,我用了ExternalInterface没有成功,那位兄台成功了可以交流交流.我用的是FlashVars, 不用改什么配置,html就可以向swf传递数据. <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-4445535400