Android基礎入門教程——7.5.5 WebView緩衝問題
本節引言:
現在很多門戶類資訊網站,比如虎嗅,ifanr,鈦媒體等等的APP,簡單點說是資訊閱讀類的APP,很多
都是直接嵌套一個WebView用來顯示相關資訊的,這可能就涉及到了WebView的緩衝了!所謂的頁面緩衝
就是指:儲存載入一個網頁時所需的HTML,JS,CSS等頁面相關的資料以及其他資源,當沒網的時候或者
網路狀態較差的時候,載入本地儲存好的相關資料!而實現這個緩衝的方式有兩種,一種是後台寫一個
下載的Service,將文章相關的資料按自己的需求下載到資料庫或者儲存到相應檔案夾中,然後下次載入
對應URL前先判斷是否存在本機快取,如果存在優先載入本機快取,不存在則執行連網請求,同時緩衝
相關資源,典型的如舊版本的36Kr,在進去後會先離線文章,然後再顯示!當然,本節要講解的不是
這種自己寫邏輯的方式,而是通過WebView本身內建的緩衝功能來快取頁面面,這種方式使用起來非常
簡單,我們只需為WebView設定開啟相關功能,以及設定資料庫的緩衝路徑即可完成緩衝!具體的
實現我們下面一一道來~
1.緩衝的分類:
首先要說的一點是緩衝的分類,我們緩衝的資料分為:頁面緩衝和資料緩衝
頁面緩衝:載入一個網頁時的html、JS、CSS等頁面或者資源資料,這些緩衝資源是由於瀏覽器
的行為而產生,開發人員只能通過配置HTTP回應標頭影響瀏覽器的行為才能間接地影響到這些快取資料。
而緩衝的索引放在:/data/data/<包名>/databases
對應的檔案放在:/data/data/package_name/cache/webviewCacheChromunm下
資料緩衝:分為AppCache和DOM Storage兩種
我們開發人員可以自行控制的就是這些緩衝資源,
AppCache:我們能夠有選擇的緩衝web瀏覽器中所有的東西,從頁面、圖片到指令碼、css等等。
尤其在涉及到應用於網站的多個頁面上的CSS和JavaScript檔案的時候非常有用。其大小目前通常是5M。
在Android上需要手動開啟(setAppCacheEnabled),並設定路徑(setAppCachePath)和容量
(setAppCacheMaxSize),而Android中使用
ApplicationCache.db來儲存AppCache資料!
DOM Storage:儲存一些簡單的用key/value對即可解決的資料,根據作用範圍的不同,有Session
Storage和Local Storage兩種,分別用於會話層級的儲存(頁面關閉即消失)和本地化儲存(除非主動
刪除,否則資料永遠不會到期)在Android中可以手動開啟DOM Storage(setDomStorageEnabled),
設定儲存路徑(setDatabasePath)Android中Webkit會為DOMStorage產生兩個檔案(my_path/localstorage/http_blog.csdn.net_0.localstorage和my_path/Databases.db)
好吧,看完上面,是不是想說一句,臥槽,什麼鬼,好複雜的樣子
當然,不要去背,知道有這些東西就好了,實際開發用到再慢慢考究,而且我們一般只關心如何
為WebView設定緩衝以及如何刪除緩衝!
我們可以看下我們下面寫的demo運行後的檔案結構,開啟DDMS的File Explorer:
嘿嘿,一目瞭然是吧~,對了另外還要說下幾種緩衝的模式:
LOAD_CACHE_ONLY: 不使用網路,唯讀取本機快取資料
LOAD_DEFAULT: 根據cache-control決定是否從網路上取資料。
LOAD_CACHE_NORMAL: API level 17中已經廢棄, 從API level 11開始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用緩衝,只從網路擷取資料.
LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否到期,或者no-cache,都使用緩衝中的資料。
總結:根據以上兩種模式,建議緩衝策略為,判斷是否有網路,有的話,使用LOAD_DEFAULT,
無網路時,使用LOAD_CACHE_ELSE_NETWORK。
接下來堆碼時間!
2.為WebView開啟緩衝功能
下面我們就來為WebView開啟緩衝功能,先來看下實現的:
運行:
流程解析:
1.進入頁面後預設載入url,然後隨便點擊一個連結跳到第二個頁面,退出APP
2.關閉wifi以及移動網路,然後重新進入,發現無網路的情況下,頁面還是載入了,
開啟第一個連結也可以載入,開啟其他連結就發現找不到網頁!
3.點擊清除緩衝,把應用關閉,重新進入,發現頁面已經打不開!
接下來是代碼實現:MainActivity.java:
public class MainActivity extends AppCompatActivity { private WebView wView; private Button btn_clear_cache; private Button btn_refresh; private static final String APP_CACHE_DIRNAME = /webcache; // web緩衝目錄 private static final String URL = http://blog.csdn.net/coder_pig; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); wView = (WebView) findViewById(R.id.wView); btn_clear_cache = (Button) findViewById(R.id.btn_clear_cache); btn_refresh = (Button) findViewById(R.id.btn_refresh); wView.loadUrl(URL); wView.setWebViewClient(new WebViewClient() { //設定在webView點擊開啟的新網頁在當前介面顯示,而不跳轉到新的瀏覽器中 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); WebSettings settings = wView.getSettings(); settings.setJavaScriptEnabled(true); //設定緩衝模式 settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); // 開啟DOM storage API 功能 settings.setDomStorageEnabled(true); // 開啟database storage API功能 settings.setDatabaseEnabled(true); String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACHE_DIRNAME; Log.i(cachePath, cacheDirPath); // 設定資料庫緩衝路徑 settings.setAppCachePath(cacheDirPath); settings.setAppCacheEnabled(true); Log.i(databasepath, settings.getDatabasePath()); btn_clear_cache.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { wView.clearCache(true); } }); btn_refresh.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { wView.reload(); } }); } //重寫回退按鈕的點擊事件 @Override public void onBackPressed() { if(wView.canGoBack()){ wView.goBack(); }else{ super.onBackPressed(); } }}
代碼很簡單,我們做的僅僅是開啟緩衝的功能,以及設定緩衝模式以及緩衝的資料的路徑而已!
3.刪除WebView的快取資料
上面的樣本,我們通過調用WebView的clearCache(true)方法,已經實現了對緩衝的刪除!
除了這種方法外,還有下述方法:
setting.setCacheMode(WebSettings.LOAD_NO_CACHE);
deleteDatabase(“WebView.db”);和deleteDatabase(“WebViewCache.db”);
webView.clearHistory();
webView.clearFormData();
getCacheDir().delete(); 手動寫delete方法,迴圈迭代刪除快取檔案夾!
當然,前面也說,我們能這直接操作的只是資料部分,而頁面緩衝是由於瀏覽器
的行為而產生,我們只能通過配置HTTP回應標頭影響瀏覽器的行為才能間接地影響到
這些快取資料。所以上述的方法僅僅是刪除的資料部分的緩衝!