基本用法
-
清單文件配置WebView
<WebView android:id="@+id/wv_news_detail" android:layout_width="match_parent" android:layout_height="match_parent" />
-
WebView加載網(wǎng)頁
//加載網(wǎng)頁鏈接 mWebView.loadUrl("https://www.google.com"); //加載本地assets目錄下的網(wǎng)頁 mWebView.loadUrl("file:///android_asset/demo.html");
-
WebView基本設(shè)置
WebSettings settings = mWebView.getSettings(); settings.setBuiltInZoomControls(true);// 顯示縮放按鈕(wap網(wǎng)頁不支持) settings.setUseWideViewPort(true);// 支持雙擊縮放(wap網(wǎng)頁不支持) settings.setJavaScriptEnabled(true);// 支持js功能
-
設(shè)置WebViewClient
mWebView.setWebViewClient(new WebViewClient() { // 開始加載網(wǎng)頁 @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); System.out.println("開始加載網(wǎng)頁了"); } // 網(wǎng)頁加載結(jié)束 @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); System.out.println("網(wǎng)頁加載結(jié)束"); } // 所有鏈接跳轉(zhuǎn)會走此方法 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { System.out.println("跳轉(zhuǎn)鏈接:" + url); view.loadUrl(url);// 在跳轉(zhuǎn)鏈接時強制在當前webview中加載 //此方法還有其他應用場景, 比如寫一個超鏈接<a href="tel:110">聯(lián)系我們</a>, 當點擊該超鏈接時,可以在此方法中獲取鏈接地址tel:110, 解析該地址,獲取電話號碼, 然后跳轉(zhuǎn)到本地打電話頁面, 而不是加載網(wǎng)頁, 從而實現(xiàn)了webView和本地代碼的交互 return true; } });
-
設(shè)置WebChromeClient
mWebView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); // 進度發(fā)生變化 System.out.println("進度:" + newProgress); } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); // 網(wǎng)頁標題 System.out.println("網(wǎng)頁標題:" + title); } });
-
WebView加載上一頁和下一頁
mWebView.goBack();//跳到上個頁面 mWebView.goForward();//跳到下個頁面 mWebView.canGoBack();//是否可以跳到上一頁(如果返回false,說明已經(jīng)是第一頁) mWebView.canGoForward();//是否可以跳到下一頁(如果返回false,說明已經(jīng)是最后一頁)
WebView高級用法
緩存
-
緩存設(shè)置
WebSettings settings = mWebView.getSettings(); //只要本地有耍铜,無論是否過期赦拘,或者no-cache唆缴,都使用緩存中的數(shù)據(jù) settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //只加載緩存 settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY); //根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù) settings.setCacheMode(WebSettings.LOAD_DEFAULT); //不加載緩存 settings.setCacheMode(WebSettings.LOAD_NO_CACHE); 什么是cache-control? cache-control是在請求網(wǎng)頁時服務(wù)器的響應頭,此響應頭用于決定網(wǎng)頁的緩存策略. 常見的取值有public(所有內(nèi)容都將被緩存), private(內(nèi)容只緩存到私有緩存中),no-cache(所有內(nèi)容都不會被緩存),max-age=xxx(緩存的內(nèi)容將在 xxx 秒后失效)等等
如圖所示:
-
清理緩存
最簡便的方式: mWebView.clearCache(true); 另外一種方式: //刪除緩存文件夾 File file = CacheManager.getCacheFileBaseDir(); if (file != null && file.exists() && file.isDirectory()) { for (File item : file.listFiles()) { item.delete(); } file.delete(); } //刪除緩存數(shù)據(jù)庫 context.deleteDatabase("webview.db"); context.deleteDatabase("webviewCache.db");
Cookie
-
Cookie設(shè)置
CookieSyncManager.createInstance(this); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); String cookie = "name=xxx;age=18"; cookieManager.setCookie(URL, cookie); CookieSyncManager.getInstance().sync();
-
獲取Cookie
CookieManager cookieManager = CookieManager.getInstance(); String cookie = cookieManager.getCookie(URL);
-
清除Cookie
CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookie(); CookieSyncManager.getInstance().sync();
Android和Js交互##
如果Js和Android實現(xiàn)了交互, 那么我們就可以在網(wǎng)頁中隨意調(diào)用本地的Java代碼, 也就是實現(xiàn)了WebView和本地代碼的交互. 一旦WebView可以操作Android本地代碼, 那么WebView的功能就會更加強大,以后我們直接在一個WebView中就幾乎可以實現(xiàn)Android的所有功能,Android原生控件就沒有了用武之地.
-
Js調(diào)用Android
WebSettings settings = mWebView.getSettings(); settings.setJavaScriptEnabled(true);//開啟js mWebView.loadUrl("file:///android_asset/demo.html");//加載本地網(wǎng)頁 mWebView.setWebChromeClient(new WebChromeClient());//此行代碼可以保證js的alert彈窗正常彈出 //核心方法, 用于處理js被執(zhí)行后的回調(diào) mWebView.addJavascriptInterface(new JsCallback() { @JavascriptInterface//注意:此處一定要加該注解,否則在4.1+系統(tǒng)上運行失敗 @Override public void onJsCallback() { System.out.println("js調(diào)用Android啦"); } }, "demo");//參1是回調(diào)接口的實現(xiàn);參2是js回調(diào)對象的名稱 //定義回調(diào)接口 public interface JsCallback { public void onJsCallback(); }
-
Android調(diào)用Js
//直接使用webview加載js就可以了 mWebView.loadUrl("javascript:wave()");
-
附上demo.html源碼
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <script language="javascript"> /* This function is invoked by the activity */ function wave() { alert("Android調(diào)用Js啦"); } </script> <body> <!-- Js調(diào)用Android代碼 --> <a onClick="window.demo.onJsCallback()"><div style="width:80px; margin:0px auto; padding:10px; text-align:center; border:2px solid #202020;" > ![](android_normal.png)<br> Click me! </div></a> </body>
</html>
注意: js回調(diào)的方法的書寫格式: onClick="window.demo.onJsCallback()
格式是: window.js回調(diào)對象的名稱(要和java代碼中設(shè)置的一致).回調(diào)方法名稱(要和java代碼中設(shè)置的一致) -
注意事項
Js調(diào)用Android的方式具有版本兼容問題. 經(jīng)測試, 在2.2, 4.0+ 系統(tǒng)上運行穩(wěn)定, 可以正常調(diào)用, 但是在2.3系統(tǒng)上運行時出現(xiàn)崩潰.原因是底層進行JNI調(diào)用時耻卡,把一個Java中的String對象當數(shù)組來訪問了梅掠,最終導致虛擬機崩潰. 基本算是一個比較嚴重的BUG趣倾,沒辦法解決,所以如果說用WebView組件想在js和java之間相互調(diào)用的話就沒辦法適應所有機型.
參考鏈接:
https://code.google.com/p/android/issues/detail?id=12987
目前一些比較前衛(wèi)的app就只使用一個WebView作為整體框架,app中的所有內(nèi)容全部使用html5進行展示.比如12306手機客戶端. 這樣做的好處就是可以實現(xiàn)跨平臺, 只需要一份h5代碼, 就可以在Android和Ios平臺上同時運行, 而且更新也更加簡便, 只需要更改服務(wù)器的h5頁面, 本地客戶端就馬上會同步更新,無需下載apk覆蓋安裝. 不過劣勢也很明顯, h5受網(wǎng)速限制,往往加載速度比較慢, 沒有原生控件流暢, 用戶體驗較差. 所以目前完全使用h5搭建app并沒有成為主流方式.
WebView的應用場景
WebView的應用場景我們無需多講, 此處我只提一點: 隨著html5的普及, 很多app都會內(nèi)嵌webview來加載html5頁面, 而且h5做的和app原生控件極其相似, 那么我們?nèi)绾伪嬲J某個頁面使用h5做的還是用原生控件做的呢?
打開開發(fā)者選項, 你會看到這樣一個選項:顯示布局邊界
勾選之后,所有原生控件布局的邊框都會顯示出來
我們現(xiàn)在在這種狀態(tài)下打開一個WebView看一眼(這是微信錢包-滴滴出行的頁面)
發(fā)現(xiàn)蛛絲馬跡了嗎? 如果是WebView的話, 只有在WebView邊緣才會顯示一個邊框, WebView內(nèi)部是沒有邊框的;如果是原生控件,怎么可能邊框這么少呢? 從而我們可以斷定,微信的滴滴出行頁面一定是用WebView加載網(wǎng)頁實現(xiàn)的, 而不是系統(tǒng)原生控件.
WebView介紹到此結(jié)束, 感謝捧場!!!
附件下載地址: <a >http://pan.baidu.com/s/1mgrPlmK</a>