在 Android 中提供了這樣一個特殊的控件 WebView,用於顯示網頁。也屬於網絡編程中的一部分,因此此次就來學習一下 WebView 的相關用法。html
WebView 最基本的用法能夠分爲如下三步:android
<?xml version="1.0" encoding="utf-8"?>
<WebView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>複製代碼
WebView mWebView = (WebView) findViewById(R.id.webview);
mWebView.loadUrl("http://www.baidu.com");複製代碼
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>複製代碼
經過以上三個步驟,就已經可使用 WebView 了。接下來再介紹一下 WebView 的更進一步的內容。web
WebView 默認是不支持 JS 的,咱們能夠經過手動修改設置來讓 WebView 支持 JS。經過 getSettings() 法獲取到 WebSettings 這個類的實例,這個類是專門用於 編程
//設置支持JS
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);複製代碼
可是在加載網頁時,Android 默認是須要調用本機中瀏覽器來打開網頁,而不是直接在本應用中展現。若是想在應用中直接展現網頁,就須要重寫 WebViewClient 類中的 shouldOverrideUrlLoading() 方法,return true 表示使用 WebView 直接展現網頁。瀏覽器
//設置在當前應用中直接展現網頁
mWebView.setWebViewClient(new MyWebViewClient());
class MyWebViewClient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view,
String url) {
view.loadUrl(url);
return true;
}
}複製代碼
WebView 自身維護了一個瀏覽歷史記錄的列表,可是在 WebView 中點擊返回鍵時,當前頁面不論是不是可以返回上一頁,都會直接退出 WebView。若是想實現和瀏覽器中同樣的到上一頁、下一頁的效果就須要藉助 WebView 的 goBack() 、goForword() 方法,同時重寫返回鍵的處理邏輯。安全
先來看看相關的方法說明:bash
boolean canGoBack ()
判斷此WebView是否能夠回到上一頁
boolean cangGoForward ()
判斷此WebView是否能夠到下一頁
boolean canGoBackOrForward (int steps)
經過傳進來的參數判斷是否可以到達指定的頁面,參數爲負表示回到上n頁,爲正表示去下n頁
void goBack ()
回到上一頁
void goForword ()
去到下一頁
void goBackOrForward (int steps)
回到上n頁或者去到下n頁,steps爲負表示後退,爲正表示前進
void clearHistory ()
清除全部的歷史紀錄複製代碼
實例代碼以下,當按下返回鍵而且 WebView 能夠回到上一頁時,就返回到上一頁,不然就按默認邏輯處理:網絡
Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)
&& mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}複製代碼
WebView 支持使用 addJavaScriptInterface() 方法來讓 JavaScript 調用 App 中的原生 Java 代碼,好比在網頁中彈出一個原生的對話框代替網頁中的 Alert。ide
void addJavascriptInterface (Object object, String name)
該方法的原理是將一個Java對象以指定的變量名字(代碼中的name)注入到JS的上下文中,這個時候這個變量在JS中能夠用於表示那個Java對象,從而調用該對象的方法。複製代碼
首先須要在 Java 代碼中建立一個 JavaScriptInterface,好比:學習
class MyJSInterface{
private Context mContext;
public MyInterface(Context context){
this.mContext = context;
}
@JavascriptInterface
public void showToast(String text){
Toast.makeText(mContext, text, 1000).show();
}
}複製代碼
以後調用 WebView 的 addJavaScriptInterface() 方法,傳入上面這個「接口」類的實例和在 JS 中變量名稱:
mWebView.addJavascriptInterface (new MyJSInterface(this),
"android");複製代碼
讓咱們看看在 HTML 頁面中是如何調用到 Java代碼的:
<html>
<head>
<meta charset="utf-8">
<title>JSDemo</title>
<script>
function toast(msg) {
window.android.showToast(msg)
}
</script>
</head>
<body>
<button type="button" id="btn_toast"
onclick="toast('show a Toast')">
toast
</button>
</body>
</html>複製代碼
能夠看到在 HTML 頁面上有一個按鈕,點擊這個按鈕就會執行 JS 中的 toast() 方法,在這個方法裏面就是調用了 window.android.showToast() 方法。
使用 addJavaScriptInterface() 須要注意如下幾點:
addJavascriptInterface() 方法中要綁定的 Java 對象及方法要運行另外的線程中,不能運行在構造它的線程中。
使用這個方法在 Android 4.2 如下的版本中會存在安全隱患,4.2 如下的版本沒有對註冊 Java 類的方法調用進行限制,因此 JavaScript 可使用反射來訪問注入對象的公共字段,以及其餘任何沒有註冊的 Java 類。攻擊者能夠經過這一漏洞對客戶端隨心所欲,包括盜取我的隱私資料等。
在 Android 4.2(targetSdkVersion ≥ 17)以上的版本中這個漏洞被解決,在註冊 Java 對象須要調用的方法前必須加上@JavascriptInterface這個註解,不然 JS 代碼不能調用該方法。
就先寫這些吧。這篇文章寫了好久,但仍是沒寫好。由於其實並無講的很深刻,只是介紹了一些皮毛,我本身的理解也還沒到位。下一篇文章努力作的更好一點,仍是關於 WebView。
下次見。
照例貼一下在學習過程當中看過的一些優秀的博客,真的從中學到了不少的東西。
developer.android.google.cn/reference/a…
谷歌開發者官網:WebView
jaq.alibaba.com/blog.htm?id…
阿里無線安全平臺:WebView 遠程代碼執行漏洞淺析
www.jianshu.com/p/e3965d363…
談談WebView的使用(做者的想法很好)
www.kymjs.com/code/2015/0…
kymjs.com/code/2015/0…張濤:深刻講解WebView(上、下)