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

1、 开发环境
    客户端:安卓+webview(vuejs)
    服务器端:tomcat 8.0

2、问题
    使用安卓原生+web(基于webpack+vuejs)的方式开发了一个安卓应用,因为web的js文件较大,大概有400k左右,每次从app中打开该页面都要从新从服务器端下载页面的html、js和图片等静态资源,反应速度比较慢了,大概须要三四秒(若是用户网速慢的话,则须要更久),体验效果就很很差。
    因此就考虑是否是能够只在第一次打开的时候下载,而后就缓存在客户端,之后只有有更新的时候才下载,可是开发人员在将安卓的webview的缓存选项设置为 LOAD_DEFAULT以后,而且在html的head加上以下meta标签,可是彷佛没有效果,有时候会缓存,有时候有从新下载,和预期的行为不一致。
     <meta http-equiv="Cache-Control" content="max-age= 604800 "/>

3、分析
    首先 安卓的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协议缓存
不过咱们通常都不会单独使用某一项。
css

      因此我估计这个meta tag在android的webview中 是没有做用的。

4、解决方案
    按照: 使用 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.   
  4.     public void doFilter(ServletRequest req, ServletResponse res,  
  5.             FilterChain chain) throws IOException, ServletException {  
  6.         HttpServletResponse response = (HttpServletResponse) res;  
  7.         // set the provided HTTP response parameters  
  8.         for (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) {  
  9.             String headerName = (String) e.nextElement();  
  10.             response.addHeader(headerName, fc.getInitParameter(headerName));  
  11.         }  
  12.         // pass the request/response on  
  13.         chain.doFilter(req, response);  
  14.     }   
  15.   
  16.     public void init(FilterConfig filterConfig) {  
  17.         this.fc = filterConfig;  
  18.     }   
  19.   
  20.     public void destroy() {  
  21.         this.fc = null;  
  22.     }   
  23.   
  24. }  




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.   
  18. <filter-mapping>  
  19.         <filter-name>NoCache</filter-name>  
  20.         <url-pattern>*.do</url-pattern>  
  21.     </filter-mapping>  
  22.     <filter-mapping>  
  23.         <filter-name>CacheForWeek</filter-name>  
  24.         <url-pattern>/images/*</url-pattern>  
  25.     </filter-mapping>  
  26.     <filter-mapping>  
  27.         <filter-name>CacheForWeek</filter-name>  
  28.         <url-pattern>/img/*</url-pattern>  
  29.     </filter-mapping>  
  30.     <filter-mapping>  
  31.         <filter-name>CacheForWeek</filter-name>  
  32.         <url-pattern>/icons/*</url-pattern>  
  33.     </filter-mapping>  
  34.     <filter-mapping>  
  35.         <filter-name>CacheForWeek</filter-name>  
  36.         <url-pattern>/ext/*</url-pattern>  
  37.     </filter-mapping>  
  38.     <filter-mapping>  
  39.         <filter-name>CacheForWeek</filter-name>  
  40.         <url-pattern>*.js</url-pattern>  
  41.     </filter-mapping>  
  42.     <filter-mapping>  
  43.         <filter-name>CacheForWeek</filter-name>  
  44.         <url-pattern>*.css</url-pattern>  
  45.     </filter-mapping>   

附录、参考资料
0)亲,你知道缓存是什么吗? http://www.javashuo.com/article/p-fprvehso-em.html 
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


相关文章
相关标签/搜索