Android WebView 緩存相關

緩存模式

// 通過設置 `WebView`的`Settings`類實現
WebSettings settings = getSettings();
// 設置緩存模式
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
  1. LOAD_DEFAULT:使用默認的緩存模式而姐,即按照網站的緩存策略來加載網頁炊邦。
  2. LOAD_NO_CACHE:不使用緩存孩擂,每次都重新從網絡上獲取數據锅纺。
  3. LOAD_CACHE_ONLY:只使用緩存,不從網絡上獲取數據肋殴。
  4. LOAD_CACHE_ELSE_NETWORK:會先使用緩存數據囤锉,如果緩存數據過期了再從網絡上獲取數據。

緩存機制

1. 瀏覽器 緩存機制(受緩存模式管理)
根據 HTTP 協議頭里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制文件緩存的機制护锤。
例如Last-Modified:標識文件在服務器上的最新更新時間

下次請求時官地,如果文件緩存過期,瀏覽器通過 If-Modified-Since 字段帶上這個時間烙懦,發(fā)送給服務器驱入,由服務器比較時間戳來判斷文件是否有修改。如果沒有修改氯析,服務器返回304告訴瀏覽器繼續(xù)使用緩存亏较;如果有修改,則返回200掩缓,同時返回最新的文件雪情。

2. Dom Storage 緩存機制(受緩存模式管理)
Android WebView提供了DOM Storage緩存機制,用于在WebView中存儲和獲取Web頁面的數據你辣。DOM Storage分為兩種類型:Session Storage和Local Storage巡通。

  • Session Storage:會話存儲是一種臨時的緩存機制,存儲的數據在用戶會話結束時會被清除舍哄。它適用于臨時保存用戶在頁面中輸入的數據或臨時狀態(tài)宴凉,以便在同一個頁面中的不同操作之間進行數據共享。
  • Local Storage:本地存儲是一種持久的緩存機制表悬,存儲的數據會一直保留在本地弥锄,直到被手動清除或過期。它適用于保存較長時間的用戶數據或頁面狀態(tài),以便在不同的會話中保持數據的連續(xù)性籽暇。

DOM Storage的使用方式類似于傳統的鍵值對存儲温治,可以通過JavaScript的localStorage和sessionStorage對象進行訪問。示例代碼如下

Android設置代碼:

 // 通過設置 `WebView`的`Settings`類實現
 WebSettings settings = getSettings();
 // 開啟DOM storage
 settings.setDomStorageEnabled(true);

javascript示例代碼:

// 存儲數據到Session Storage
sessionStorage.setItem('key', 'value');

// 從Session Storage獲取數據
var value = sessionStorage.getItem('key');

// 存儲數據到Local Storage
localStorage.setItem('key', 'value');

// 從Local Storage獲取數據
var value = localStorage.getItem('key');

需要注意的是图仓,DOM Storage中存儲的數據是基于域名和協議的罐盔,不同域名或協議之間的Web頁面無法訪問彼此的存儲數據。如果需要在WebView中使用DOM Storage救崔,可以通過WebSettings類的方法進行相關設置惶看,例如開啟DOM Storage功能、設置DOM Storage的大小等六孵。
總的來說纬黎,DOM Storage緩存機制為開發(fā)者提供了一種方便的方式來在WebView中進行數據的存儲和獲取,以實現更靈活和交互性的Web應用程序劫窒。

3. Application Cache 緩存機制(不受緩存模式管理)
Android WebView提供了Application Cache緩存機制用于在離線狀態(tài)下加載并緩存Web應用程序的資源文件本今。這使得Web應用程序能夠在沒有網絡連接的情況下正常運行,提供更好的用戶體驗主巍。
Application Cache使用一個描述文件(通常是一個名為"manifest.appcache"的文件)來定義要緩存的資源列表冠息。這個描述文件包含了需要緩存的各個資源的URL,這些資源可以是HTML文件孕索、CSS文件逛艰、JavaScript文件、圖像等搞旭。一旦描述文件被下載和解析散怖,相關的資源將被下載并存儲在本地緩存中。

設置Android代碼如下:

// 通過設置WebView的settings來實現
 WebSettings settings = getSettings();

 String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
 settings.setAppCachePath(cacheDirPath);
 // 1. 設置緩存路徑

 settings.setAppCacheMaxSize(20*1024*1024);
 // 2. 設置緩存大小

 settings.setAppCacheEnabled(true);
 // 3. 開啟Application Cache存儲機制

使用Application Cache的步驟如下:

  1. 在Web應用程序的主HTML文件中肄渗,通過<html>標簽的manifest屬性指定描述文件的URL镇眷。
<html manifest="manifest.appcache">
  1. 在描述文件中,列出需要緩存的資源URL翎嫡。
CACHE MANIFEST
# version 1.0

CACHE:
index.html
style.css
script.js
image.png
  1. 當Web應用程序處于在線狀態(tài)時欠动,描述文件將被下載并解析,緩存中的資源將被下載并存儲在本地钝的。此后翁垂,即使離線狀態(tài)下訪問Web應用程序,緩存的資源也能夠被加載和使用硝桩。

需要注意的是,Application Cache是基于域名的枚荣,因此不同域名的Web應用程序無法共享緩存碗脊。另外,使用Application Cache時要小心緩存的更新和失效問題,可以通過更新文件的版本號或使用其他緩存管理策略來解決衙伶。

總之祈坠,Application Cache提供了一種強大的緩存機制,使得Web應用程序能夠在離線狀態(tài)下正常工作矢劲,并提供更好的用戶體驗赦拘。

4. Web SQL Database 緩存機制(不受緩存模式管理)
基于SQL的數據庫緩存機制,它通過在移動設備上存儲數據庫文件來實現緩存芬沉。

具體來說躺同,當WebView加載HTML頁面時,如果頁面中包含Web SQL Database相關的腳本(如JavaScript)丸逸,則會創(chuàng)建一個與數據庫相關的對象(如window.openDatabase)蹋艺。通過這個對象,可以執(zhí)行SQL語句來創(chuàng)建黄刚、查詢捎谨、更新或刪除數據庫中的數據。同時憔维,WebView會將數據庫文件保存在應用的緩存目錄中涛救,以便在后續(xù)的頁面加載過程中重復使用。

 // 通過設置WebView的settings實現
 WebSettings settings = getSettings();
 // 設置緩存路徑
 String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
 settings.setDatabasePath(cacheDirPath);
 // 開啟 數據庫存儲機制
 settings.setDatabaseEnabled(true);

5. Indexed Database 緩存機制(不受緩存模式管理)
基于NoSQL數據庫的緩存機制业扒,它通過存儲字符串的Key-Value對來提供緩存功能检吆。

Indexed Database不同于傳統的關系型數據庫,它是由key和value存儲的NoSQL數據庫凶赁,集合了DomStorgage和WebSQLDatabase存的優(yōu)點咧栗。在Android WebView中,Indexed Database通過存儲在客戶端的DOM數據來實現緩存虱肄。當WebView加載HTML頁面時致板,如果頁面中包含DOM相關的數據,Indexed Database會將數據存儲在客戶端咏窿,以便在后續(xù)的頁面加載過程中重復使用斟或。

// 通過設置WebView的settings實現
WebSettings settings = getSettings();
// 只需設置支持JS就自動打開IndexedDB存儲機制
// Android 在4.4開始加入對 IndexedDB 的支持,只需打開允許 JS 執(zhí)行的開關就好了集嵌。
settings.setJavaScriptEnabled(true);

清理緩存

1. 清除HTTP緩存

WebView.clearCache(false)

2. 清除HTTP緩存和Dom Storage緩存

WebView.clearCache(true)

離線包

可將更新頻率較低萝挤、常用的靜態(tài)資源文件(CSS、圖片等)等H5的頁面和資源進行打包后下發(fā)到客戶端根欧,并由客戶端直接解壓到本地儲存中怜珍。在加載H5請求網絡資源之前攔截網絡請求并進行檢測,如果成功匹配到本地的靜態(tài)資源就直接從本地讀取進行替換凤粗,從而免除從服務端獲取酥泛。

下面是一個簡單的示例,演示如何使用 WebView 的 WebViewClient 類和 JavaScript 的 window 對象來實現這一功能:

  • 首先,在你的 Activity 或 Fragment 中柔袁,獲取 WebView 的實例呆躲,并為其設置一個 WebViewClient:
WebView myWebView = (WebView) findViewById(R.id.my_webview);  
myWebView.setWebViewClient(new MyWebViewClient());
  • 接下來,創(chuàng)建一個自定義的 WebViewClient 類(例如捶索,MyWebViewClient)插掂,并重寫其中的 shouldOverrideUrlLoading() 方法:
class MyWebViewClient extends WebViewClient {  
    @Override  
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {  
        // 在這里攔截和處理網絡請求  
        String url = request.getUrl().toString();  
        // 判斷是否是你要攔截的URL,如果是腥例,則進行處理辅甥;如果不是,則調用super.shouldOverrideUrlLoading()方法繼續(xù)加載  
        if (url.startsWith("http://example.com/")) {  
            // 在這里處理網絡請求院崇,例如通過 JavaScript 與 Java 之間的橋接接口調用 Android 代碼  
            // ...  
            return true; // 返回true表示攔截該請求肆氓,false表示繼續(xù)加載  
        } else {  
            // 繼續(xù)加載其他URL  
            return super.shouldOverrideUrlLoading(view, request);  
        }  
    }  
}

在上述代碼中,我們通過重寫 shouldOverrideUrlLoading() 方法來攔截網絡請求底瓣。在方法中谢揪,我們獲取請求的 URL,并根據需要進行處理捐凭。如果 URL 是你要攔截的特定 URL(例如以 http://example.com/ 開頭)拨扶,則可以在這里通過 JavaScript 與 Java 之間的橋接接口調用 Android 代碼。如果 URL 不是你要攔截的特定 URL茁肠,則調用 super.shouldOverrideUrlLoading() 方法繼續(xù)加載患民。

WebView 中使用本地 JavaScript 和 CSS 文件,可以通過以下步驟實現:

  • 將 JavaScript 和 CSS 文件保存到應用的資源目錄中垦梆,例如 res/raw 目錄匹颤。
  • 在 WebView 的加載過程中,使用 WebView.loadUrl() 方法加載 JavaScript 和 CSS 文件托猩。例如印蓖,使用 WebView.loadUrl("file:///android_res/raw/myscript.js") 加載 JavaScript 文件,使用 WebView.loadUrl("file:///android_res/raw/mystyle.css") 加載 CSS 文件京腥。

示例代碼如下:

WebView myWebView = (WebView) findViewById(R.id.my_webview);  
myWebView.getSettings().setJavaScriptEnabled(true);  
myWebView.loadUrl("file:///android_res/raw/myscript.js");  
myWebView.loadUrl("file:///android_res/raw/mystyle.css");  
myWebView.loadUrl("http://example.com");
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末邻薯,一起剝皮案震驚了整個濱河市惶楼,隨后出現的幾起案子馏艾,更是在濱河造成了極大的恐慌四濒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠气,死亡現場離奇詭異厅各,居然都是意外死亡,警方通過查閱死者的電腦和手機预柒,發(fā)現死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門讯检,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琐鲁,“玉大人卫旱,你說我怎么就攤上這事人灼。” “怎么了顾翼?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵投放,是天一觀的道長。 經常有香客問我适贸,道長灸芳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任拜姿,我火速辦了婚禮烙样,結果婚禮上,老公的妹妹穿的比我還像新娘蕊肥。我一直安慰自己谒获,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布壁却。 她就那樣靜靜地躺著批狱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪展东。 梳的紋絲不亂的頭發(fā)上赔硫,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音盐肃,去河邊找鬼爪膊。 笑死,一個胖子當著我的面吹牛砸王,可吹牛的內容都是我干的推盛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼处硬,長吁一口氣:“原來是場噩夢啊……” “哼小槐!你這毒婦竟也來了?” 一聲冷哼從身側響起荷辕,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤凿跳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后疮方,有當地人在樹林里發(fā)現了一具尸體控嗜,經...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年骡显,在試婚紗的時候發(fā)現自己被綠了疆栏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曾掂。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖壁顶,靈堂內的尸體忽然破棺而出珠洗,到底是詐尸還是另有隱情,我是刑警寧澤若专,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布许蓖,位于F島的核電站,受9級特大地震影響调衰,放射性物質發(fā)生泄漏膊爪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一嚎莉、第九天 我趴在偏房一處隱蔽的房頂上張望米酬。 院中可真熱鬧,春花似錦趋箩、人聲如沸赃额。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爬早。三九已至,卻和暖如春启妹,著一層夾襖步出監(jiān)牢的瞬間筛严,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工饶米, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桨啃,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓檬输,卻偏偏與公主長得像照瘾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丧慈,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內容