如何确定Android WebView何时完全加载完成?

28
我想知道如何确定 WebView 完全 加载完成。
让我定义一下完成
  • 所有重定向已发生
  • 页面可见,没有任何内容需要加载
这个问题的错误答案包括: WebViewClient.onPageFinished() - 如果有重定向加载页面,它会多次触发。并且在页面显示之前就触发了。 PictureListener.onNewPicture() - 每次屏幕更改和 AFAICT 的每个重定向都会触发。我怎么知道哪次触发是最后一次? WebChromeClient.onProgressChanged() - 与 onPageFinished 相同的问题。(在 David 建议该解决方案后添加) Thread.sleep(5000) - 很明显,为什么不接受这种方式。
当然,能够 clever 地结合上述方法并且可以正常工作的方式是最完美的。
你问我为什么要知道这个? 因为我想在 WebView 完全加载完成后注入一些 javascript 一次

1
WebViewClient.onPageFinished()中添加“bad answer”:根据此处的内容,如果页面中有多个iframe,则它会多次触发。 - uTubeFan
@Carlos Man 我和你当时处于完全相同的位置。唯一让我的情况更糟的是PictureListener已经被弃用了。你能想出解决方案吗?我需要计算WebView中页面的总数,为此我需要将内容宽度除以屏幕宽度。但在页面完全呈现在屏幕上之前,我无法这样做。有什么解决办法吗? - Arunavh Krishnan
@ArunavhKrishnan 嗯,上次我看这个是三年前了。最后我认为我做的与被接受的答案类似。祝你好运! - Carlos Rendon
1
不必等到页面加载完成后再注入JavaScript,您可以使用立即调用函数表达式(IIFE)或添加一个事件侦听器来监听DOM准备就绪事件。有DOMContentLoadedwindow.onloaddocument.ready等事件可供选择。 - Fred
2个回答

9

感谢David Caunt的建议,让我们来看看响应头。

我发现以下方法效果不错:

不要让webview执行HTTP请求,而是自己执行,这样可以检查重定向的HTTP状态码。跟随重定向链。当到达不是重定向的请求时,设置一个标志并通过webview.loadDataWithBaseURL将数据发送到webview。在WebViewClient.onPageFinished()中检查标志,以知道所有重定向都已完成。此时可以注入javascript。当然,页面本身可能会在此时进行一些javascript操作,很难知道,因此将javascript添加延迟(例如500ms)以允许DOM稳定下来。setTimeout(function(){/* your code */}, 500)


1
有用的知识!至于页面本身的JavaScript,很难检测到它何时完成。 - David Snabel-Caunt
1
@Carlos Rendon,非常感谢你提供的优秀概述。我很惊讶这个功能没有被实现在WebView或其任何卫星接口中。这个功能是如此需要,但WebView团队唯一能做的就是弃用PictureListener。你有什么想法为什么会这样吗? - uTubeFan
1
顺便提一下,事实证明我不是唯一一个梦想在WebView中访问HTTP响应头的人。 - uTubeFan
客户端重定向怎么样?如果根据定义为空,你如何在HTTP状态码中捕获它? - WebViewer

1
你有考虑过设置自己的WebChromeClient吗?
看起来onProgressUpdated可以在页面完全加载时通知您。
这似乎是Android内置浏览器使用的方法。

谢谢您的建议。不幸的是,这与WebViewClient.onPageFinished()存在相同的问题,由于重定向而触发多次。例如,在“gmail.com”上,它会触发3次,进度为100。 - Carlos Rendon
1
下一个进度值为0的时候是什么时候?如果它在响应后立即触发重定向,那么可以安全地使用超时并假设您正在进行最后一个请求。否则,我会寻找一种获取响应头或类似内容的方法。 - David Snabel-Caunt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接