使用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;
}