學(xué)知識(shí)就是要掌握一些概念的內(nèi)涵和外延。So,讓我們看看與WebView相關(guān)的幾個(gè)概念吧认臊。
概念 | 內(nèi)涵 | 外延 |
---|---|---|
WebView | 一個(gè)絕對(duì)布局容器 | 用來展示或渲染W(wǎng)eb頁面 |
WebSettings | 一個(gè)抽象類寨辩,包含對(duì)WebView的設(shè)置方法吓懈。 | 用來對(duì)WebView進(jìn)行設(shè)置,比如支持JS靡狞、緩存模式等 |
WebViewClient | 這個(gè)類的方法有一個(gè)特點(diǎn)耻警,就是參數(shù)的第一項(xiàng)就是WebView,其他項(xiàng)是事件或數(shù)據(jù)信息甸怕。WebView通過該類對(duì)外通知頁面加載相關(guān)的消息 | 用來在頁面加載的各個(gè)階段進(jìn)行業(yè)務(wù)處理甘穿,處理加載錯(cuò)誤情況,攔截頁面內(nèi)和頁面外的請(qǐng)求 |
WebChromeClient | WebView通過該類梢杭,通知獲取到站點(diǎn)圖標(biāo)温兼、標(biāo)題、加載進(jìn)度武契,以及JS對(duì)話框等 | 用來更好地展示頁面和交互 |
理解了上面幾個(gè)概念后募判,我們就可以處理一般的業(yè)務(wù)需求了。比如
設(shè)置緩存
緩存模式
獲取到WebSettings然后調(diào)用其中的設(shè)置方法就可以了咒唆。
WebSettings webSettings = webView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
緩存模式有LOAD_DEFAULT(默認(rèn))届垫、LOAD_CACHE_ELSE_NETWORK(先緩存后網(wǎng)絡(luò))、LOAD_NO_CACHE(不要緩存)全释、LOAD_CACHE_ONLY(只要緩存)装处,可以根據(jù)業(yè)務(wù)要求選擇。
緩存機(jī)制
(1)瀏覽器緩存機(jī)制
- 概念:通過 HTTP 協(xié)議頭里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制文件緩存的機(jī)制浸船。
- 適用:適用于 Web 的靜態(tài)資源文件妄迁。
(2)Dom Storage(Web Storage)
- 概念:通過存儲(chǔ)字符串的 Key/Value 對(duì)來提供找前,并提供 5MB (不同瀏覽器可能不同,分 HOST)的存儲(chǔ)空間(Cookies 才 4KB)判族。分為 sessionStorage 和 localStorage躺盛。
- 適用:代替掉將一些不需要讓服務(wù)器知道的信息存儲(chǔ)到 cookies 里的這種傳統(tǒng)方法。
webSettings.setDomStorageEnabled(true);
(3)Web SQL Database
- 概念:基于 SQL 的數(shù)據(jù)庫存儲(chǔ)機(jī)制形帮,用于存儲(chǔ)適合數(shù)據(jù)庫的結(jié)構(gòu)化數(shù)據(jù)槽惫。
- 適用:Web SQL Database 存儲(chǔ)機(jī)制不再推薦使用,將來也不再維護(hù)辩撑,而是推薦使用 AppCache 和 IndexedDB界斜。
webSettings.setDatabaseEnabled(true);
final String dbPath = getApplicationContext().getDir("db", Context.MODE_PRIVATE).getPath();
webSettings.setDatabasePath(dbPath);
(4)Application Cache(AppCache)
- 概念:為支持 Web App 離線使用而開發(fā)的緩存機(jī)制。以文件為單位進(jìn)行緩存合冀,且文件有一定更新機(jī)制各薇。
- 適用:AppCache 是對(duì)瀏覽器緩存機(jī)制的補(bǔ)充,不是替代君躺。不推薦使用了,標(biāo)準(zhǔn)也不會(huì)再支持棕叫。
webSettings.setAppCacheEnabled(true);
final String cachePath = getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath();
webSettings.setAppCachePath(cachePath);
webSettings.setAppCacheMaxSize(5*1024*1024);
(5)Indexed Database
- 概念:NoSQL 數(shù)據(jù)庫林螃,類似于 Dom Storage 的 key-value 的存儲(chǔ)方式,但功能更強(qiáng)大俺泣,且存儲(chǔ)空間更大疗认。
- 適用:用于存儲(chǔ)大塊或復(fù)雜結(jié)構(gòu)的數(shù)據(jù),提供更大的存儲(chǔ)空間伏钠,使用起來也比較簡單横漏。可以作為 Web SQL Database 的替代熟掂。不太適合靜態(tài)文件的緩存缎浇。
webSettings.setJavaScriptEnabled(true);
(6)File System API
- 概念:為 Web App 提供了一個(gè)虛擬的文件系統(tǒng),運(yùn)行在沙盒中
- 適用:任何需要通過文件來管理數(shù)據(jù)打掘,或通過文件系統(tǒng)進(jìn)行數(shù)據(jù)管理的場景都比較適合华畏。到目前,Android 系統(tǒng)的 Webview 還不支持 File System API尊蚁。
處理頁面導(dǎo)航
方法一
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
方法二
@Override
public void onBackPressed() {
if (contentWeb.canGoBack()) {
contentWeb.goBack();
} else {
super.onBackPressed();
}
}
與Activity/Fragment生命周期相適應(yīng)
參考WebViewFragment實(shí)現(xiàn)
/**
* A fragment that displays a WebView.
* <p>
* The WebView is automically paused or resumed when the Fragment is paused or resumed.
*/
public class WebViewFragment extends Fragment {
private WebView mWebView;
private boolean mIsWebViewAvailable;
public WebViewFragment() {
}
/**
* Called to instantiate the view. Creates and returns the WebView.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mWebView != null) {
mWebView.destroy();
}
mWebView = new WebView(getActivity());
mIsWebViewAvailable = true;
return mWebView;
}
/**
* Called when the fragment is visible to the user and actively running. Resumes the WebView.
*/
@Override
public void onPause() {
super.onPause();
mWebView.onPause();
}
/**
* Called when the fragment is no longer resumed. Pauses the WebView.
*/
@Override
public void onResume() {
mWebView.onResume();
super.onResume();
}
/**
* Called when the WebView has been detached from the fragment.
* The WebView is no longer available after this time.
*/
@Override
public void onDestroyView() {
mIsWebViewAvailable = false;
super.onDestroyView();
}
/**
* Called when the fragment is no longer in use. Destroys the internal state of the WebView.
*/
@Override
public void onDestroy() {
if (mWebView != null) {
mWebView.destroy();
mWebView = null;
}
super.onDestroy();
}
/**
* Gets the WebView.
*/
public WebView getWebView() {
return mIsWebViewAvailable ? mWebView : null;
}
}
展示頁面加載進(jìn)度
舊有的實(shí)現(xiàn)
參考Android: The progress bar in the window's title does not display文中的一種實(shí)現(xiàn)亡笑,然而看了下發(fā)布時(shí)間是2010.06。注意:那時(shí)候用的是Android 2.3横朋,BrowserActivity不是繼承自AppCompactActivity仑乌,使用的主題也不是AppCompact主題。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
requestWindowFeature(Window.FEATURE_PROGRESS);
currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");
setContentView(R.layout.browser);
setProgressBarIndeterminateVisibility(true);
setProgressBarVisibility(true);
try {
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new browserActivityClient());
mWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
setProgress(progress * 100);
if(progress == 100) {
setProgressBarIndeterminateVisibility(false);
setProgressBarVisibility(false);
}
}
});
mWebView.loadUrl(currentURL);
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
自定義實(shí)現(xiàn)
- 思路:在webView內(nèi)部或外部添加一個(gè)ProgressBar(水平樣式),并通過WebChromeClient獲知頁面的加載進(jìn)度晰甚,進(jìn)而調(diào)整ProgressBar的進(jìn)度衙传。
-
實(shí)現(xiàn):
WebChromeClient webChromeClient = new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress == 100) { progressBar.setVisibility(View.GONE); } else { progressBar.setVisibility(View.VISIBLE); progressBar.setProgress(newProgress); } } }; webView.setWebViewClient(webViewClient);