【问题标题】:window.location called too often?window.location 调用太频繁?
【发布时间】:2011-02-07 16:49:56
【问题描述】:

我正在尝试拦截 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 内得到一个调用。如果我每隔 50 毫秒打一次电话,我就会接听他们所有人。我认为浏览器正在对此进行一些优化。

我想我可以这样解决这个问题:不要使用window.location,更改为将本机对象嵌入到javascript中,并在javascript中调用该对象上的方法。我只是想知道为什么会这样。有更熟悉 JS 的大神分享一下吗?

谢谢

【问题讨论】:

  • “如果我间隔 50 毫秒打一次电话,我会告诉他们所有人。”你如何让通话间隔 50 毫秒?通过 window.setInterval 并将 callNative() 调用放入 setInterval 调用的代码中?
  • setTimeout("callNative", 50*i)
  • 你可以尝试做window.location.href = "...",但这似乎是一种很奇怪的方式。也许,用这样的 URL 创建图像?

标签: javascript android


【解决方案1】:

我遇到了完全相同的问题。您可以通过创建 iframe 来做到这一点。我使用本机 url 创建 iframe,然后在 2 秒后删除 iframe,这样我们就不会在 DOM 上放置太多。对我来说就像一个魅力。您可以根据需要创建任意数量的 iframe。

我还在 iframe url 上添加了一个缓存破坏器,尽管我不确定它是否需要。比抱歉更安全。

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上是否完全相同,但从判断问题和其他答案来看,我猜是一样的。

【讨论】:

  • 我在 android 上检查并添加 iframe 确实触发了 shouldOverrideUrlLoading 方法
【解决方案2】:

我猜想加载 URL 是异步的(在 URL 被解析之前阻止脚本的执行可能是个坏主意)。因此,设置window.location 大概只会排队加载新 URL,这将在不同的线程中完成。

等待 50 毫秒是一种可能有效也可能无效的技巧。你需要找到不同的方法。你需要一些东西来保证这些 URL 中的每一个都会被解析。如果顺序无关紧要,您可以像有人建议的那样使用图像。否则,您可以使用原生 JavaScript 接口(这可能是更好的方法)。

【讨论】:

  • 你说的很对,换位置不适合这种工作。我实际上正在采取另一种方法。我刚刚发布了这个问题,开始讨论浏览器正在做的优化。
  • 这不是优化,它只是一个分离的过程,即 JavaScript 只是请求更改位置,但不同的线程实际上会执行此更改。当其他线程开始执行更改时,JavaScript 线程已经设置了位置count 次。
猜你喜欢
  • 2012-10-30
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多