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




  • 相关阅读:
    深入理解RunLoop
    Universal Framework for iOS
    Framework的制作流程,Xode-6.0.1
    Xcode 6制作动态及静态Framework
    Volley与Picasso的对比
    WebView全面学习(二)-- Native与js双方通信
    WebView全面学习(一)--常用类和方法
    Hybrid框架安全隐患分析
    Android笔记--View绘制流程源码分析(二)
    Android笔记--View绘制流程源码分析(一)
  • 原文地址:https://www.cnblogs.com/strinkbug/p/5836534.html
Copyright © 2011-2022 走看看