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è)置的最大容量時的策略阁猜。