我在h5的页面曾经想要同步获得native的系统时间。但目前比较常见的js与webview互相调用的方法,包括伪协议、alert弹窗侦听等,都是异步调用的过程。使用addjavascriptinterface接口的方法当然能够从功能上完成,但这种做法已被证明具有严重的安全漏洞,那么我们就没有同步调用的方法了吗,下面分享一种侦听prompt函数的方法,欢迎大家指正。
首先我们看下js的prompt函数的作用和原理:
js的prompt函数用于显示可提示用户进行输入的对话框。当Prompt显示输入对话框时,若点击取消,则返回js的结果为 null。若点击确认,则返回输入字段当前显示的文本。在用户点击确定按钮或取消按钮把对话框关闭之前,它将阻止用户对浏览器的所有输入。同时,在js调用 prompt()方法时,浏览器将暂停对 JavaScript 代码的执行。在用户作出响应之前,不会执行下一条语句。由此就给我们提供了一种同步调用native的思路:
1、 在web页面中调用prompt()方法,传递默认的message给终端。此时js挂起等待响应。
2、 在webview中侦听onJsPrompt接口,捕获特定message协议的prompt()方法,屏蔽输入框(我们不需要输入框,只需要用到prompt的原理),同时根据协议调用native相应的方法。
3、 利用onJsPrompt中的result.confirm()方法将回调带给js。
由此便完成了js同步调用native的过程,下面上关键源码:
Js中代码:
//准备调用prompt函数和处理返回参数
function showPrompt()
{
var result = invokeNativeMethod("getVersion");
if(result)
{
alert(result);
}
else
{
alert("本地返回为空");
}
}
//触发prompt()函数并制定协议
function invokeNativeMethod(methodName)
{
var result=prompt("test_" + methodName,"");
return result;
}
webview中代码:
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
{
//判断是否伪协议
if(message.startsWith("test_"))
{
String methodname = message.split("_")[1];
//根据协议判断js需要调用的是哪个native方法
if(methodname.equals("getVersion"))
{
result.confirm(getVersion());
}
else
{
result.confirm("无此方法");
}
}
result.cancel();
return true;
}