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


相關文章
相關標籤/搜索