您的位置:首页 > 移动开发 > Android开发

Android WebView 中 JS 与Java之间通信

2017-11-23 16:21 417 查看

Java调用JS

在WebView中,Java调用JS的方法,实现方式是相对简单的。

采用如下形式即可:

WebView.loadUrl(“javascript:function()”)


查阅官方文档也给出了相应实例:

class JsObject {
@JavascriptInterface
public String toString() { return "injectedObject"; }
}
webview.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "injectedObject");
webView.loadData("", "text/html", null);
webView.loadUrl("javascript:alert(injectedObject.toString())");


JS调用Java

JS调用Java方法,需要采用WebView提供的一些API,同时需要前端同学和App同学约定一些类名和方法名。

方案一

setJavaScriptEnabled

调用
WebSettings.setJavaScriptEnabled()
启用支持JavaScript功能

addJavaScriptInterface

void addJavascriptInterface (Object object, String name)


此方法将提供的Java对象注入WebView中。该对象使用提供的名称(即name)注入到主框架的JavaScript上下文中。这允许从JavaScript访问Java对象的方法。对于定位到API级别JELLY_BEAN_MR1及更高版本的应用程序,只能使用有@JavascriptInterface注解的公共方法可以从JavaScript访问。对于针对API级别JELLY_BEAN或更低版本的应用程序,可以访问所有公共方法(包括继承的方法),请参阅下面的重要安全说明以了解其含义。

注意 在注入对象之前应该启用JavaScript。并且只用页面被重新加载,注入的对象才会出现在JavaScript中。

class JsObject {
@JavascriptInterface
public String toString() { return "injectedObject"; }
}
webview.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "injectedObject");


在此例中,向WebView注册一个名叫
injectedObject
JsObject
Java对象,然后在JS中可以通过
injectedObject.toString()
访问此方法,最终可以调用到Java代码中,从而实现了JS与Java代码的交互。

当然这种方式在Android 4.2版本一下存在安全漏洞,具体请查看Android WebView的Js对象注入漏洞解决方案

方案二

在WebView有一个方法,叫setWebChromeClient,可以设置WebChromeClient对象,而这个对象中有三个方法,分别是onJsAlert,onJsConfirm,onJsPrompt,当js调用window对象的对应的方法,即window.alert,window.confirm,window.prompt,WebChromeClient对象中的三个方法对应的就会被触发,我们是不是可以利用这个机制,自己做一些处理呢?答案是肯定的。

public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
return false;
}


相对于alert、comfirm的使用场景,prompt就显得特别少,使用它实现JS调用Java的功能再合适不过了。

Android JSBridge的原理与实现

规定协议:

jsbridge://className:callbackAddress/methodName?jsonObj

以WindVane为例,

hybrid://OptionsMenuJsBridge:19778/noteList?{}

hybrid://OptionsMenuJsBridge:19780/modifyNote?{“id”:33184}

而协议需要通过编写JS代码以通用的方式生成,前端只需要关注调用方式即可

window.WindVane.call(className, methodName, jsonObj, successCallback, failureCallback);

在Java中,会以defaulatValue.equals(“wv_hybrid”)作为判断条件来处理响应协议,执行具体指定的方法和解析参数

public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
if(TaoLog.getLogStatus()) {
TaoLog.i("WVWebChromeClient", "onJsPrompt: %s; defaultValue: %s; url: %s", new Object[]{message, defaultValue, url});
}

if(view instanceof IWVWebView && WVEventService.getInstance().onEvent(2003, (IWVWebView)view, url, new Object[]{message, defaultValue, result}).isSuccess) {
return true;
} else if(defaultValue != null && defaultValue.equals("wv_hybrid:")) {
WVJsBridge.getInstance().callMethod((WVWebView)view, message);
result.confirm("");
return true;
} else {
return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android webview hybrid