Android webView 緩存 Cache + HTML5離線功能解決(轉(zhuǎn))

原:http://blog.csdn.net/lxy_tap/article/details/52583810

WebView的緩存可以分為頁面緩存和數(shù)據(jù)緩存。
頁面緩存是指加載一個網(wǎng)頁時的html计呈、JS、CSS等頁面或者資源數(shù)據(jù)片择。這些緩存資源是由于瀏覽器的行為而產(chǎn)生碴犬,開發(fā)者只能通過配置HTTP響應(yīng)頭影響瀏覽器的行為才能間接地影響到這些緩存數(shù)據(jù)。

     他們的索引存放在/data/data/package_name/databases下倒信。他們的文件存放在/data/data/package_name/cache/xxxwebviewcachexxx下照棋。文件夾的名字在2.x和4.x上有所不同资溃,但都文件夾名字中都包含webviewcache。

        數(shù)據(jù)緩存分為兩種:AppCache和DOM Storage(Web Storage)烈炭。他們是因為頁面開發(fā)者的直接行為而產(chǎn)生溶锭。所有的緩存數(shù)據(jù)都由開發(fā)者直接完全地掌控。

AppCache使我們能夠有選擇的緩沖web瀏覽器中所有的東西符隙,從頁面趴捅、圖片到腳本、css等等霹疫。尤其在涉及到應(yīng)用于網(wǎng)站的多個頁面上的CSS和JavaScript文件的時候非常有用拱绑。其大小目前通常是5M。
在Android上需要手動開啟(setAppCacheEnabled)丽蝎,并設(shè)置路徑(setAppCachePath)和容量(setAppCacheMaxSize)
Android中Webkit使用一個db文件來保存AppCache數(shù)據(jù)(my_path/ApplicationCache.db)

      如果需要存儲一些簡單的用key/value對即可解決的數(shù)據(jù)猎拨,DOM Storage是非常完美的方案。根據(jù)作用范圍的不同屠阻,有Session Storage和Local Storage兩種红省,分別用于會話級別的存儲(頁面關(guān)閉即消失)和本地化存儲(除非主動刪除,否則數(shù)據(jù)永遠不會過期)国觉。

在Android中可以手動開啟DOM Storage(setDomStorageEnabled)吧恃,設(shè)置存儲路徑(setDatabasePath)
Android中Webkit會為DOM Storage產(chǎn)生兩個文件(my_path/localstorage/http_h5.m.taobao.com_0.localstorage和my_path/localstorage/Databases.db)

       另外,在Android中清除緩存時麻诀,如果需要清除Local Storage的話痕寓,僅僅刪除Local Storage的本地存儲文件是不夠的,內(nèi)存里面有緩存數(shù)據(jù)蝇闭。如果再次進入頁面呻率,Local Storage中的緩存數(shù)據(jù)同樣存在。需要殺死程序運行的當(dāng)前進程再重新啟動才可以丁眼。

HTML5的離線應(yīng)用功能可以使得WebApp即使在網(wǎng)絡(luò)斷開的情況下仍能正常使用筷凤,這是個非常有用的功能昭殉。近來工作中也要用到HTML5離線應(yīng)用功能苞七,由于是在Android平臺上做藐守,所以自然而然的選擇Webview來解析網(wǎng)頁。但如何使Webivew支持HTML5離線應(yīng)用功能呢蹂风,經(jīng)過反復(fù)摸索和上網(wǎng)查找資料卢厂,反復(fù)做試驗終于成功了。

首先需配置webview的的一些屬性惠啄,假設(shè)activity中已經(jīng)有了一個Webview的實例對象慎恒,名為m_webview,然后增加以下代碼:

WebSettings webseting = m_webview.getSettings();  
    webseting.setDomStorageEnabled(true);             
        webseting.setAppCacheMaxSize(1024*1024*8);//設(shè)置緩沖大小撵渡,我設(shè)的是8M  
    String appCacheDir = this.getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath();      
        webseting.setAppCachePath(appCacheDir);  
        webseting.setAllowFileAccess(true);  
        webseting.setAppCacheEnabled(true);  
        webseting.setCacheMode(WebSettings.LOAD_DEFAULT);  

webview可以設(shè)置一個WebChromeClient對象融柬,在其onReachedMaxAppCacheSize函數(shù)對擴充緩沖做出響應(yīng)。代碼如下:

m_webview.setWebChromeClient(m_chromeClient);  
    private WebChromeClient m_chromeClient = new WebChromeClient(){  
        //擴充緩存的容量    
    @Override  
    public void onReachedMaxAppCacheSize(long spaceNeeded,    
                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {    
            quotaUpdater.updateQuota(spaceNeeded * 2);    
        }         
    };  

其次要修改http服務(wù)器中的配置趋距,使其支持text/cache-manifest粒氧,我使用的是apache服務(wù)器,是windows版本的节腐,在apache的conf文件夾中找到mime.types文件外盯,打開后在文件的最后加上
“text/cache-manifest

mf manifest”,重啟服務(wù)器即可翼雀。這一步很重要饱苟,我就是因為服務(wù)器端沒有配置這個,所以失敗了好多次狼渊,最后是在附錄鏈接1的回復(fù)中找到的線索箱熬。

經(jīng)過以上設(shè)置Webview就可以支持HTML5的離線應(yīng)用了。

附錄鏈接1中說緩沖目錄應(yīng)該是getApplicationContext().getCacheDir().getAbsolutePath();但我經(jīng)過試驗后發(fā)現(xiàn)設(shè)置那個目錄不起作用囤锉,可能是Android版本不同吧坦弟,我的是Android4.0.3,而他的可能是以前的Android版本吧官地。

緩沖目錄使用

getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath()是從附錄鏈接2中找到的線索酿傍。

附錄鏈接:
1.http://alex.tapmania.org/2010/11/html5-cache-android-webview.html
2.http://johncookie.iteye.com/blog/1182459
3.HTML5 Offline官方文檔:http://www.w3.org/TR/html5/offline.html#manifests

原因:

webview加載 服務(wù)端的網(wǎng)頁,為了減少訪問壓力驱入,用html5緩存技術(shù)赤炒,本地建了數(shù)據(jù)庫,在手機瀏覽器里 可以顯示頁面亏较,換成webView就不行了莺褒。

public class efan_NewsReader extendsActivity {
        /** Called when the activity is first created. */
        @Override
        publicvoidonCreate(Bundle savedInstanceState)
        {   
                super.onCreate(savedInstanceState);   
                setContentView(R.layout.main);            
                WebView myWebView=(WebView)findViewById(R.id.my_webview);   
                myWebView.setWebViewClient(newWebViewClient());   
                WebSettings settings = myWebView.getSettings();
               // 開啟javascript設(shè)置
               settings.setJavaScriptEnabled(true);  
               // 設(shè)置可以使用localStorage
               settings.setDomStorageEnabled(true);
               // 應(yīng)用可以有數(shù)據(jù)庫
               settings.setDatabaseEnabled(true);   
               String dbPath =this.getApplicationContest().getDir("database", Context.MODE_PRIVATE).getPath();
               settings.setDatabasePath(dbPath);
               // 應(yīng)用可以有緩存
               settings.setAppCacheEnabled(true);            
               String appCaceDir =this.getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath();
               settings.setAppCachePath(appCaceDir);
                
               myWebView.loadUrl("http://10.10.35.47:8080/html5test/test.htm");
        }
}

HTML5 page source code:

 <htmlmanifest="mymanifest.manifest">
    <head>
<metahttp-equiv="Content-Type"content="text/html; content="no-cache"charset=utf-8" />
<scripttype="text/javascript"src="js/jquery-1.6.1.min.js"></script>
 
<script>
$(document).ready(function(){      
 
    databaseTest();
});
 
function databaseTest(){
 
 
    //open database
     var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);  
 
      db.transaction(function (tx) {            
      tx.executeSql('CREATE TABLE IF NOT EXISTS testHtml (id unique, contentText)');
      tx.executeSql('INSERT INTO testHtml (contentText) VALUES ("insert data test!")');  
       });  
 
     db.transaction(function(tx){           
     tx.executeSql('SELECT * FROM testHtml',[],function(tx,result){
            var len=result.rows.length;
            var msg = "<p>Found rows: " + len + "</p>";  
             $("#testinfo").append(msg);
        },null);
     });   
 
 
}
 
</script>
 
 
</head>
<body>
    <div>here is test info:</div>
    <divid="testinfo"></div>
</body>

其他設(shè)置還有:
settings.setCacheMode(WebSettings.LOAD_DEFAULT); // 默認使用緩存
settings.setAppCacheMaxSize(810241024); //緩存最多可以有8M
settings.setAllowFileAccess(true); // 可以讀取文件緩存(manifest生效)

in WebChromeClient :

myWebView.setWebChromeClient(newWebChromeClient()
{   
        @Override   
        publicvoidonExceededDatabaseQuota(String url, String databaseIdentifier,
                       longcurrentQuota,longestimatedSize,longtotalUsedQuota,
                       WebStorage.QuotaUpdater quotaUpdater)   
        {        
                quotaUpdater.updateQuota(estimatedSize * 2);   
        }
}
myWebView.setWebChromeClient(newWebChromeClient()
{
    // 擴充緩存的容量   
        @Override   
        publicvoidonReachedMaxAppCacheSize(longspaceNeeded,longtotalUsedQuota,
                       WebStorage.QuotaUpdater quotaUpdater)   
        {        
                quotaUpdater.updateQuota(spaceNeeded * 2);
    }
}

按照范例,我成功的解決了我的問題雪情,而且之前彈出框所出現(xiàn)的找不到數(shù)據(jù)(提示:underfine)也解決了遵岩,這個應(yīng)該是當(dāng)初數(shù)據(jù)庫沒設(shè)所引起的。

WebView中存在著兩種緩存:網(wǎng)頁數(shù)據(jù)緩存(存儲打開過的頁面及資源)、H5緩存(即appcache)尘执。

一舍哄、網(wǎng)頁緩存

1、緩存構(gòu)成
/data/data/package_name/cache/
/data/data/package_name/database/webview.db
/data/data/package_name/database/webviewCache.db

2誊锭、緩存模式
較難理解的是以下兩個模式:
LOAD_DEFAULT表悬,根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)。
LOAD_CACHE_ELSE_NETWORK丧靡,只要本地有蟆沫,無論是否過期,或者no-cache温治,都使用緩存中的數(shù)據(jù)饭庞。
如:m.taobao.com的cache-control為no-cache,在模式LOAD_DEFAULT下熬荆,無論如何都會從網(wǎng)絡(luò)上取數(shù)據(jù)但绕,如果沒有網(wǎng)絡(luò),就會出現(xiàn)錯誤頁面惶看;在LOAD_CACHE_ELSE_NETWORK模式下捏顺,無論是否有網(wǎng)絡(luò),只要本地有緩存纬黎,都使用緩存幅骄。本地沒有緩存時才從網(wǎng)絡(luò)上獲取。
m.sina.com.cn的cache-control為max-age=60本今,在兩種模式下都使用本地緩存數(shù)據(jù)拆座。

總結(jié):根據(jù)以上兩種模式,建議緩存策略為冠息,判斷是否有網(wǎng)絡(luò)挪凑,有的話,使用LOAD_DEFAULT逛艰,無網(wǎng)絡(luò)時躏碳,使用LOAD_CACHE_ELSE_NETWORK。

3散怖、清除緩存
clearCache(boolean)菇绵。
CacheManager.clear。高版本中需要調(diào)用隱藏API镇眷。

4咬最、控制大小
無系統(tǒng)API支持。
可選方式:定時統(tǒng)計緩存大小欠动、按時間順序刪除緩存永乌。

二、H5緩存

1、緩存構(gòu)成
根據(jù)setAppCachePath(String appCachePath)提供的路徑翅雏,在H5使用緩存過程中生成的緩存文件硝桩。

2、緩存模式
無模式選擇枚荣,通過setAppCacheEnabled(boolean flag)設(shè)置是否打開。默認關(guān)閉啼肩,即橄妆,H5的緩存無法使用。

3祈坠、清除緩存
找到調(diào)用setAppCachePath(String appCachePath)設(shè)置緩存的路徑害碾,把它下面的文件全部刪除就OK了。

4赦拘、控制大小
通過setAppCacheMaxSize(long appCacheMaxSize)設(shè)置緩存最大容量慌随,默認為Max Integer。
同時躺同,可能通過覆蓋WebChromeClient.onReachedMaxAppCacheSize(long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater)來設(shè)置緩存超過先前設(shè)置的最大容量時的策略阁猜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蹋艺,隨后出現(xiàn)的幾起案子剃袍,更是在濱河造成了極大的恐慌,老刑警劉巖捎谨,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件民效,死亡現(xiàn)場離奇詭異,居然都是意外死亡涛救,警方通過查閱死者的電腦和手機畏邢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來检吆,“玉大人舒萎,你說我怎么就攤上這事〔渑妫” “怎么了逆甜?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長致板。 經(jīng)常有香客問我交煞,道長,這世上最難降的妖魔是什么斟或? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任素征,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘御毅。我一直安慰自己根欧,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布端蛆。 她就那樣靜靜地躺著凤粗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪今豆。 梳的紋絲不亂的頭發(fā)上嫌拣,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音呆躲,去河邊找鬼异逐。 笑死,一個胖子當(dāng)著我的面吹牛插掂,可吹牛的內(nèi)容都是我干的灰瞻。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼辅甥,長吁一口氣:“原來是場噩夢啊……” “哼酝润!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起璃弄,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤袍祖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谢揪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蕉陋,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年拨扶,在試婚紗的時候發(fā)現(xiàn)自己被綠了凳鬓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡患民,死狀恐怖缩举,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情匹颤,我是刑警寧澤仅孩,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站印蓖,受9級特大地震影響辽慕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赦肃,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一溅蛉、第九天 我趴在偏房一處隱蔽的房頂上張望公浪。 院中可真熱鬧,春花似錦船侧、人聲如沸欠气。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽预柒。三九已至,卻和暖如春袁梗,著一層夾襖步出監(jiān)牢的瞬間宜鸯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工围段, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人投放。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓奈泪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灸芳。 傳聞我的和親對象是個殘疾皇子涝桅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,841評論 25 707
  • 0. 前言 前面有被用戶投訴 APP 流量消耗厲害: 于是乎考慮了流量方面的問題。暫時 APP 中涉及流量的幾個方...
    zyl06閱讀 23,967評論 5 62
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    小莊bb閱讀 3,493評論 3 25
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,743評論 0 19
  • 2017-7-24(九十四) 感恩 —— 愛人一大早給爸爸轉(zhuǎn)了四萬烙样,讓爸爸的店鋪可以很好的開始運營冯遂。祈愿愛人財富的...
    慢慢花開閱讀 162評論 0 0