Android WebViewClient 回调调用过于频繁

Posted

技术标签:

【中文标题】Android WebViewClient 回调调用过于频繁【英文标题】:Android WebViewClient callbacks called too often 【发布时间】:2011-06-30 07:04:09 【问题描述】:

当我打电话给WebView#loadUrl 时,我希望我只接到一个WebViewClient#onPageFinished 电话,而没有WebViewClient#shouldOverrideUrlLoading 电话。但是,我得到了一个 WebViewClient#shouldOverrideUrlLoading(我通过始终调用 WebView#loadUrl 并返回 true 来实现),然后是两个具有相同 URL 的 WebViewClient#onPageFinished 调用。

我正在加载的页面使用了很多 ajax 请求。 ajax 请求是否调用WebViewClient?我的页面没有任何元刷新。

这很令人沮丧。我做错了吗?

【问题讨论】:

【参考方案1】:

这是来自a google groups discussion I started on the topic 的交叉帖子。

我做了更多的研究,我想我了解正在发生的一切。

这是我的WebViewClient

public class MyWebViewClient extends WebViewClient 
  @Override
  public void onPageStarted(WebView view, String url, Bitmap favicon) 
    System.out.println("onPageStarted: " + url);
  

  @Override
  public boolean shouldOverrideUrlLoading(WebView webView, String url) 
    System.out.println("shouldOverrideUrlLoading: " + url);
    webView.loadUrl(url);
    return true;
  

  @Override
  public void onPageFinished(WebView webView, String url) 
    System.out.println("onPageFinished: " + url);
  

我的服务器有以下 URL 重定向:

http://example.com/resource -> http://example.com/user-name/resource
http://example.com/logout.jsp -> http://example.com/login/logout
http://example.com/login/logout -> http://example.com/login

这些 URL 是我无法控制的服务器的一部分,所以我只需要处理这些行为。

这是加载http://example.com/resource的输出

onPageStarted: http://example.com/resource
onPageStarted: http://example.com/user-name/resource
shouldOverrideUrlLoading: http://example.com/user-name/resource
onPageFinished: hhttp://example.com/user-name/resource

此时,我的WebView 有空白内容。我必须等到第二个onPageFinished 之后才能获取我的内容。

onPageStarted: http://example.coms/user-name/resource
onPageFinished: http://example.com/user-name/resource

这是加载http://example.com/logout.jsp的输出

onPageStarted: http://example.com/logout.jsp
onPageStarted: http://example.com/login/logout
shouldOverrideUrlLoading: http://example.com/login/logout
onPageFinished: http://example.com/login/logout
onPageStarted: http://example.com/login/logout
onPageStarted: http://example.com/login
shouldOverrideUrlLoading: http://example.com/login
onPageFinished: http://example.com/login

同样,此时,我的WebView 有一个空白页。我必须等到第三个onPageFinished 才能从WebView 获取我的内容。

onPageStarted: http://example.com/login
onPageFinished: http://example.com/login

根据文档,我预计不会出现这种行为。请注意,onPageStarteds 和 onPageFinisheds 的数量不平衡。我特别不喜欢 onPageFinished 被重定向 URL 调用的方式,但 WebView 不包含我的内容。我知道这种行为可能是不可改变的,但至少应该记录这种意外行为。

【讨论】:

@heath_borders 你知道 webview 内部到底发生了什么吗,我正在调查它,因为我因多次调用 onPageFinished 而遇到问题。【参考方案2】:
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) 
    System.out.println("shouldOverrideUrlLoading: " + url);
    return true;

您不需要显式调用 webView.loadUrl(url)。通过覆盖返回 true 将自动让您现有的 webview 来处理新的页面加载。通过不必要地调用它,它会在原始周期(onPageStarted -> onPageFinished)中间在该 webView 上启动一个全新的网页加载周期,因此总共触发了额外的回调周期。

【讨论】:

感谢您的回答。我什至无法再访问服务器,因此无法在相同条件下对其进行测试。另外,我确信WebView 的行为在我发布后的几年里发生了变化。可能需要一段时间才能验证这是否正确。

以上是关于Android WebViewClient 回调调用过于频繁的主要内容,如果未能解决你的问题,请参考以下文章

HTTP状态码webview android, WebViewClient

在 Android WebViewClient 中获取空白页

Android WebViewClient url 重定向(Android URL 加载系统)

Android - 在 AsyncTask 中设置 WebViewClient 会导致 NullPointerException

Android WebViewClient,有404时不会调用onErrorReceived

如何从不在 Android 的 API 26 上的 WebView 获取 WebviewClient 实例?