Android常用控件WebView,項目中大家並不陌生,接下來介紹下他的簡單使用。
1.基本用法
-
清單文件配置WebView
<WebView
android:id="@+id/wv_news_detail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
-
WebView加載網頁
//加載網頁鏈接
mWebView.loadUrl("http://www.itheima.com");
//加載本地assets目錄下的網頁
mWebView.loadUrl("file:///android_asset/demo.html");
-
WebView基本設置
WebSettings settings = mWebView.getSettings();
settings.setBuiltInZoomControls(true);// 顯示縮放按鈕(wap網頁不支持)
settings.setUseWideViewPort(true);// 支持雙擊縮放(wap網頁不支持)
settings.setJavaScriptEnabled(true);// 支持js功能
-
設置WebViewClient
mWebView.setWebViewClient(new WebViewClient() {
// 開始加載網頁
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
System.out.println("開始加載網頁了");
}
// 網頁加載結束
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
System.out.println("網頁加載結束");
}
// 所有鏈接跳轉會走此方法
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
System.out.println("跳轉鏈接:" + url);
view.loadUrl(url);// 在跳轉鏈接時強制在當前webview中加載
//此方法還有其他應用場景, 比如寫一個超鏈接<a href="tel:110">聯繫我們</a>, 當點擊該超鏈接時,可以在此方法中獲取鏈接地址tel:110, 解析該地址,獲取電話號碼, 然後跳轉到本地打電話頁面, 而不是加載網頁, 從而實現了webView和本地代碼的交互
return true;
}
});
-
設置WebChromeClient
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
// 進度發生變化
System.out.println("進度:" + newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
// 網頁標題
System.out.println("網頁標題:" + title);
}
});
-
WebView加載上一頁和下一頁
mWebView.goBack();//跳到上個頁面
mWebView.goForward();//跳到下個頁面
mWebView.canGoBack();//是否可以跳到上一頁(如果返回false,說明已經是第一頁)
mWebView.canGoForward();//是否可以跳到下一頁(如果返回false,說明已經是最後一頁)
2.WebView高級用法
緩存
-
緩存設置
什麼是cache-control?cache-control是在請求網頁時服務器的響應頭,此響應頭用於決定網頁的緩存策略.常見的取值有public(所有內容都將被緩存), private(內容只緩存到私有緩存中),no-cache(所有內容都不會被緩存),max-age=xxx(緩存的內容將在 xxx 秒後失效)等等WebSettings settings = mWebView.getSettings();
//只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//只加載緩存
settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
//根據cache-control決定是否從網絡上取數據
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
//不加載緩存
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
如圖所示:
-
清理緩存
最簡便的方式:
另外一種方式:mWebView.clearCache(true);
//刪除緩存文件夾
File file = CacheManager.getCacheFileBaseDir();
if (file != null && file.exists() && file.isDirectory()) {
for (File item : file.listFiles()) {
item.delete();
}
file.delete();
}
//刪除緩存數據庫
context.deleteDatabase("webview.db");
context.deleteDatabase("webviewCache.db");
3.Cookie
-
Cookie設置
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();
4.Android和Js交互
如果Js和Android實現了交互, 那麼我們就可以在網頁中隨意調用本地的Java代碼, 也就是實現了WebView和本地代碼的交互. 一旦WebView可以操作Android本地代碼, 那麼WebView的功能就會更加強大,以後我們直接在一個WebView中就幾乎可以實現Android的所有功能,Android原生控件就沒有了用武之地.
-
Js調用Android
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);//開啓js
mWebView.loadUrl("file:///android_asset/demo.html");//加載本地網頁
mWebView.setWebChromeClient(new WebChromeClient());//此行代碼可以保證js的alert彈窗正常彈出
//核心方法, 用於處理js被執行後的回調
mWebView.addJavascriptInterface(new JsCallback() {
@JavascriptInterface//注意:此處一定要加該註解,否則在4.1+系統上運行失敗
@Override
public void onJsCallback() {
System.out.println("js調用Android啦");
}
}, "demo");//參1是回調接口的實現;參2是js回調對象的名稱
//定義回調接口
public interface JsCallback {
public void onJsCallback();
}
-
Android調用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調用Js啦");
}
</script>
<body>
<!-- Js調用Android代碼 -->
<a onClick="window.demo.onJsCallback()"><div style="width:80px;
margin:0px auto;
padding:10px;
text-align:center;
border:2px solid #202020;" >
<img id="droid" src="android_normal.png"/><br>
Click me!
</div></a>
</body>
注意: js回調的方法的書寫格式: onClick="window.demo.onJsCallback() 格式是: window.js回調對象的名稱(要和java代碼中設置的一致).回調方法名稱(要和java代碼中設置的一致)
-
注意事項
Js調用Android的方式具有版本兼容問題. 經測試, 在2.2, 4.0+ 系統上運行穩定, 可以正常調用, 但是在2.3系統上運行時出現崩潰.原因是底層進行JNI調用時,把一個Java中的String對象當數組來訪問了,最終導致虛擬機崩潰. 基本算是一個比較嚴重的BUG,沒辦法解決,所以如果說用WebView組件想在js和java之間相互調用的話就沒辦法適應所有機型.
參考鏈接: https://code.google.com/p/android/issues/detail?id=12987
http://www.2cto.com/kf/201108/101375.html
目前一些比較前衛的app就只使用一個WebView作爲整體框架,app中的所有內容全部使用html5進行展示.比如12306手機客戶端. 這樣做的好處就是可以實現跨平臺, 只需要一份h5代碼, 就可以在Android和Ios平臺上同時運行, 而且更新也更加簡便, 只需要更改服務器的h5頁面, 本地客戶端就馬上會同步更新,無需下載apk覆蓋安裝. 不過劣勢也很明顯, h5受網速限制,往往加載速度比較慢, 沒有原生控件流暢, 用戶體驗較差. 所以目前完全使用h5搭建app並沒有成爲主流方式.
5.WebView的應用場景
WebView的應用場景我們無需多講, 此處我只提一點: 隨着html5的普及, 很多app都會內嵌webview來加載html5頁面, 而且h5做的和app原生控件極其相似, 那麼我們如何辨認某個頁面使用h5做的還是用原生控件做的呢
打開開發者選項, 你會看到這樣一個選項:顯示佈局邊界
勾選之後,所有原生控件佈局的邊框都會顯示出來
我們現在在這種狀態下打開一個WebView看一眼(這是微信錢包-滴滴出行的頁面)
如果是WebView的話, 只有在WebView邊緣纔會顯示一個邊框, WebView內部是沒有邊框的;如果是原生控件,怎麼可能邊框這麼少呢? 從而我們可以斷定,微信的滴滴出行頁面一定是用WebView加載網頁實現的, 而不是系統原生控件.