我正在尝试拦截window.location更改以在Android应用中执行一些本机工作。更具体地说,我在WebViewClient中覆盖了这个调用:
public boolean shouldOverrideUrlLoading(WebView view, String url)
查找以“native://”开头的任何内容。 JavaScript代码是这样的。
function callNative() {
window.location = "native://doSomeNativeWork()";
}
function callNativeManyTimes(count) {
for(i = 0 ; i < count ; i ++) {
callNative();
}
}
<a href="javascript:callNativeManyTimes(40);" class="btn large">DoSomeNativeWork</a><br/>
我看到的问题是,如果我很快地调用“window.location = something”很多次(比如上面的代码中),我只会在本机代码端的WebViewClient中调用一次。如果我拨打电话50ms,我会得到所有人。我在想这个浏览器正在做一些优化。
我想我可以像这样解决这个问题:不要使用window.location,更改为将本机对象嵌入到javascript中,并在javascript中调用该对象上的方法。我只是想知道为什么会这样。有人可以更熟悉机智JS分享一些见解吗?
由于
答案 0 :(得分:2)
我遇到了同样的问题。你可以通过创建iframe来做到这一点。我使用原生网址创建iframe,然后在2秒后删除iframe,这样我们就不会在DOM上放置太多。对我来说就像一个魅力。您可以根据需要创建任意数量的iframe。
我还在iframe网址上加了一个缓存破坏程序,即使我不确定它是否需要。更好的安全然后抱歉。
function callNative(url){
var _frame = document.createElement('iframe');
_frame.width=0; _frame.height=0;_frame.frameBorder=0;
document.body.appendChild(_frame);
if (url.indexOf('?') >= 0){
url = url + "&cb=";
}else{
url = url + "?cb=";
}
_frame.src = url + Math.round(Math.random()*1e16);
// Remove the iframe
setTimeout(function(){document.body.removeChild(_frame);}, 2000);
}
function callNativeManyTimes(count) {
for(i = 0 ; i < count ; i ++) {
callNative('native://doSomeNativeWork()');
}
}
<a href="javascript:callNativeManyTimes(40);" class="btn large">DoSomeNativeWork</a><br/>
请注意,我在iOS上使用了上述方法。不确定它在Android上是否完全相同,但从判断问题和其他答案来看,我猜它是一样的。
答案 1 :(得分:1)
我猜测加载URL是异步的(在解析URL之前阻止脚本的执行可能是个坏主意)。因此,设置window.location
可能只会排队加载新URL,这将在不同的线程中完成。
等待50毫秒是一个可能或可能不起作用的黑客。你需要找到一种不同的方法。您需要一些东西来保证每个URL都能得到解决。如果订单无关紧要,您可以像有人建议的那样使用图片。否则,您可以使用本机JavaScript接口(这可能是更好的方法)。