在Android中可能因为业务场景需要,JS需要调用Native业务逻辑代码,Native需要通知JS,也即需要实现JS和Native之间通信;
##Java通知JS方式:
WebView.load("javascrpt:method("+param+");");##JS通知Java有如下几种方式
具体使用示例参见官网描述
但该方案存在版本兼容问题,在4.2版本以下系统上存在安全漏洞,JS能够根据反射能访问注入的对象公有域。当WebView包含恶意代码时,攻击者可以以意想不到的方式来控制宿主App,使用这种方式需要特别小心。一般不建议使用此种方式
参见Here
不能翻墙的可以看看这个
我们可以通过onJsPrompt这种方式来实现JS和Native之间交互。 每当JS调用prompt方法时Native的WebView所绑定的WebChromeClient的onJsPrompt方法会被触发
我们看看官方的说明
大意是告诉Client去显示一个提示框。如果返回true,WebView就会认为Client将要处理dialog并调用JsPromptResult合适方法(confirm/cancel)通知WebView;如果返回false,默认值将被返回给JS;方法默认返回false。
JS在调用prompt(message, defaultValue)方法时会传递2个参数给Native,分别对应onJSPrompt的第二、三个参数 我们只要和JS那边达成一套协议
myschem://className/methodName?data={param:xxx,callback:xxx}className: JS调用Native的全路径名 methodName: JS调用Native具体方法 param: Native类方法名的入参 callback: Native调用JS的方法
Native从onJsPrompt方法接受到的message参数符合上面格式后,就可以知道调用Native哪个类哪个方法并且可以将Native产生的数据通过callback方式通知给JS,这是目前Native和JS之间交互的主流的通信方式。 示例代码:
@Override public boolean onJsPrompt(final WebView view, String url, final String message, String defaultValue, final JsPromptResult result) { //parse message boolean isLegal = isLegal(message); if (isLegal) { //invoke Native method //notice js result WebView.load("javascrpt:${callback}("+${param}+");"); result.confirm("lightweight data"); } else { result.confirm(); } return true; }注意事项
返回值必须true,如果返回false,WebView会弹一个很丑的对话框,阻塞用户体验在返回前必须调用confirm方法传递给confirm的值必须是轻量级的数据onJsPrompt方法运行在WebView创建的线程中(一般是UI线程)onJsPrompt的操作不要过重在Activity销毁时避免JS的调用##3、H5白屏的问题解决方式
如果JS和Native交互使用到onJsprompt方式请确保遵循上面注意事项因为JavaScript是单线程,如果上面方式还是解决不了白屏问题,请让H5同学使其JS调用放到后台线程