zoukankan      html  css  js  c++  java
  • 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-Controlgzip提升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)亲,你知道缓存是什么吗?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-Controlgzip提升tomcat应用性能(整理), http://qin686-163-com.iteye.com/blog/287782




  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/strinkbug/p/5836534.html
Copyright © 2011-2022 走看看