Android 中WebView 的使用

我们都知道Webview 是用来加载网页的,底层使用Webkit 来实现的。首先要在清单文件里注册网络请求权限

1
<uses-permission android:name="android.permission.INTERNET" />

如果使用外部程序(浏览器)打开

1
2
3
Uri uri = Uri.parse("http://www.example.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

如果使用WebView 来打开

1
2
3
WebView webview = new WebView(this);
setContentView(webview);
webview.loadUrl("http://www.zhihu.com"); // notice http://

加载网页

一共有四种不同的方法,基本上一看就一目了然。可以使用字符串或者网页,设置MimeType 和编码。

1
2
3
4
void	loadData(String data, String mimeType, String encoding)
void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)
void loadUrl(String url)
void loadUrl(String url, Map<String, String> additionalHttpHeaders)

之前遇到过一个问题,比如我们有个Base Url 后面的参数需要动态来传,我们可以使用Uri 的构造器来拼凑(当然你也可以手拼字符串)。

1
2
3
4
5
6
mUrl = new Uri.Builder()
.encodedPath(BASE_URL + "/user")
.appendQueryParameter("age", age)
.appendQueryParameter("sex", sex)
.appendQueryParameter("token", token)
.build().toString();

设置一些高级的属性(比如:JS)

当WebView 第一次初始化,会获得一组默认值。
我们可以使用WebView.getSettings() 方法来获取Settings 对象,来自定义设置一些属性。
当WebView 被摧毁,调用WebView.getSettings(),将会抛出IllegalStateException。

1
2
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

一般会有set 和get 两组方法,有设置JS,缩放,字体大小,use-agent,保存表单数据等等其他属性。

监听状态

1
myWebView.setWebViewClient(new WebViewClient());

我们可以继承WebViewClient,重写下面的一些方法。

1
2
3
boolean shouldOverrideUrlLoading(WebView view, String url) // 可以重写
void onPageStarted(WebView view, String url, Bitmap favicon) // 初始化一些数据
void onPageFinished(WebView view, String url) // 网页加载完成

shouldOverrideUrlLoading() 方法,我们可以设置404 页面,在js 中传输数据,在这里捕获,特殊处理。例如:在网页中打开App,就可以处理。

除了上面常用的,还有拦截请求,获取的错误,重写键盘事件,认证等等。

我们 也可以使用WebChromeClient,加载WebView 的一些属性,比如alert,prompt,进度条,可以让WebView 更加丰富。

和JS 交流

在Java 代码中调用JS

1
2
String value = "javascript:call()";
mWebView.loadUrl(value);

除了上面这样,我们也可以给方法传出参数,进行计算。
在JS 代码中调用Java

1
2
3
function sumToJava(num1, num2) {
window.android.onSumResult(num1 + num2);
}
1
2
3
4
@JavascriptInterface
public void onSumResult(int result) {
WebViewActivity.this.showToast("result: " + result);
}

需要注意的是@JavascriptInterface 需要将TargetSDK 设置为17 或者更高,而且也有安全问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript">
function showAndroidToast() {
window.android.showToast("Hello Android!");
}

function save() {
alert("3242");
}

function call(num) {
alert(num);
}

function sumToJava(num1, num2) {
window.android.onSumResult(num1 + num2);
}
</script>

1
2
3
4
5
6
7
8
mWebView.setWebViewClient(new WebViewClient());
mWebView.addJavascriptInterface(new WebAppInterface(this), "android"); // js 中的名字
mWebView.setWebChromeClient(new WebChromeClient() {});

String save = "javascript:save()";
String call = "javascript:call(\"" + "content" + "\")";
call = "javascript:sumToJava(1, 2)";
mWebView.loadUrl(call);

如果我们不适用@JavascriptInterface,可以使用WebView 重写shouldOverrideUrlLoading(WebView view, String url),将发送的链接捕获处理。

1
2
3
4
5
<script>
function openApp() {
window.location = open_app://com.android.camera;
}
</script>

参考