相比于Native App和 Web App,Hybrid App 凭借其迭代灵活、控制自如、多端同步的优势在应用市场上越发显得优胜,主要得力于,其将变更频繁的部分产品功能使用 H5 开发并在客户端中借助 WebView 控件嵌入应用当中。所以,开发中我们总会遇到原生 Java 代码与网页中的 Js 代码之间相互调用从而产生的交互问题。
Java与 Js 彼此调用的前提是设置 WebView 支持 JavaScript 功能:
mWebView.getSettings().setJavaScriptEnabled(true);
Java调用 Js
![](https://i-blog.csdnimg.cn/blog_migrate/6723c1c1100252c44a4991eebc50b6d2.png)
第一步,在网页中使用Js 定义提供给 Java 访问的方法,就像普通方法定义一样,如:
<script type="text/javascript">
function javaCallJs(message){
alert(message);
}
</script>复制代码
第二步,在Java 代码中按照 "javascript:XXX" 的 Url 格式使用 WebView 加载访问即可:
mWebView.loadUrl("javascript:javaCallJs(" + "'Message From Java'" + ")");复制代码
注意:String 类型的参数需要使用单引号 “'” 包裹,数组类型的参数则不用,如:javascript:javaCallJs([01, 02, 03]),其他复杂类型的参数可以转换为 Json 字符串的形式传递。
Js 调用 Java
第一步,在Java 对象中定义 Js 访问的方法,如:
@JavascriptInterfacepublic void jsCallJava(String message){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}复制代码
注意事项:提供给Js 访问的属性和方法必须定义为 public 类型,并且添加注解 @JavascriptInterface。在 API 17 及更高版本的系统中,任何暴露给 Js 访问的 Java 接口都需要添加这个注解,否则会报异常:Uncaught TypeError: Object [object Object] has no method 'XXX'。系统这种做法也是为了降低应用的安全隐患,因为在之前的版本中,Js 可以通过反射的方式访问注入 WebView 中的 Java 对象的 public 类型 field 和 method,从而随意修改宿主程序。
第二步,将提供给Js 访问的接口内容所属的 Java 对象注入 WebView 中:
mWebView.addJavascriptInterface(MainActivity.this, "main");复制代码
addJavascriptInterface(Object object, String name) 参数说明:object 表示 Js 访问的接口内容所在的 Java 对象;name 表示 Js 调用 Java 代码时的接口名称,与 Js 中的调用保持一致即可。
第三步,Js 按照指定的接口名访问 Java 代码,有如下两种写法:
<button type="button" onClick="javascript:main.jsCallJava('Message From Js')" >Js Call Java</button>
<!--<button typ