使用WebView的時候,native與js的交互是個幾乎不可避免的問題。
下面我們看看兩者交互都有哪些種套路吧。
WebView 中JS與Native相互調用的幾中方式:
Native 調用 JS 中的方法
- API >= 19
webView.evaluateJavascript(method, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(TAG, "onReceiveValue value=" + value);
}
});
- API < 19
String methodStr = "javascript:" + method;
webView.loadUrl(methodStr);
一般兩個一起使用就是這么寫了:
public void nativeCallJSMethod(String method) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
webView.evaluateJavascript(method, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(TAG, "onReceiveValue value=" + value);
}
});
} else {
String methodStr = "javascript:" + method;
webView.loadUrl(methodStr);
}
}
JS 調用 Native 方法
- 攔截URL
這是最low的辦法。 JS事件做跳轉,native端攔截跳轉,并根據url做相應的處理。 - Add JavaScript Interface
webView.addJavascriptInterface(object, "name")
需要注意的是,在API<17的設備上,因為沒有注解限制,是有安全風險的。
- WebChromeClient 的 onJsPrompt
解析自定義defaultValue 來執行具體功能。
以下示例代碼來自Cordova java源碼。
@Override
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, final JsPromptResult result) {
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
String handledRet = parentEngine.bridge.promptOnJsPrompt(origin, message, defaultValue);
if (handledRet != null) {
result.confirm(handledRet);
} else {
dialogsHelper.showPrompt(message, defaultValue, new CordovaDialogsHelper.Result() {
@Override
public void gotResult(boolean success, String value) {
if (success) {
result.confirm(value);
} else {
result.cancel();
}
}
});
}
return true;
}