在Android WebViewClient中,什么被认为是onPageFinished?

19
我正在尝试在Android WebView中完成网页加载后执行某个操作。我设置了一个WebViewClient来利用onPageFinished事件回调。但是,在经过一些测试后,似乎它在我的onPageFinished代码触发之前并不会等待页面上所有JS都加载完毕。Google文档中说:
public void onPageFinished (WebView view, String url)

在API Level 1中添加 通知宿主应用程序页面加载完成。该方法仅针对主框架调用。当调用onPageFinished()方法时,渲染图片可能还没有更新。要获取新图片的通知,请使用onNewPicture(WebView, Picture)。

  

参数

     

view    发起回调的WebView。

     

url     页面的URL。

1)onPageFinished只等待DOM加载完成吗?

2)有没有办法检测页面上的任何JS是否已经完成?如果有,我应该使用什么?

我在WebViewClient中没有找到任何与此目的相关的内容。我不想添加延迟,因为我的用户可能处于EDGE或LTE网络中。

3个回答

7
您需要实现来自WebChromeClient的回调。onPageFinished()是由WebViewClient提供的API。还有另一个名为WebChromeClient的接口,它提供了您正在寻找的进度信息: http://developer.android.com/reference/android/webkit/WebChromeClient.html#onProgressChanged(android.webkit.WebView, int)
打开上面的链接,查找onProgressChanged(WebView view, int newProgress) - 'newProgress'变量给出了已完成页面加载的百分比。当它达到100时,您将拥有一个有效页面。由于服务器端重定向等原因,无法可靠地使用onPageFinished()进行此操作。
我不知道您所说的“当页面上的JS完成时”的意思。也许您可以澄清一下您的意思?

我试图确定与页面相关的Javascript何时完成运行。从我的工作中,我看到onPageFinished在页面的HTML部分完成加载时被调用 - 不一定是Javascript完成时。您指向的方法并没有给我所需要的答案,“有没有一种方法可以检测页面上任何[Javascript]何时完成?如果有,我应该使用什么?” - Steven
当你说“JS on the page finishes”时,你的意图是什么?你是指“执行完成”吗?如果是这样,那么你可能想要 a.)通过利用addJavascriptInterface()方法(WebViewClient类的成员)在HTML代码(Web)和Java代码(Android)之间创建JavaScript接口;或者b.)在JS函数中添加一些自定义日志或警报,并使用WebChromeClient类的onConsoleMessage()/onJsAlert()方法进行检测。 - Sdr

3

From:

https://chromium.googlesource.com/chromium/src.git/+/master/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java

    @Override
    public void didFinishNavigation(final String url, boolean isInMainFrame, boolean isErrorPage,
            boolean hasCommitted, boolean isSameDocument, boolean isFragmentNavigation,
            Integer pageTransition, int errorCode, String errorDescription, int httpStatusCode) {
        ...
        if (client != null && isFragmentNavigation) {
            client.getCallbackHelper().postOnPageFinished(url);
        }
    }

    @Override
    public void didFailLoad(
            boolean isMainFrame, int errorCode, String description, String failingUrl) {
        AwContentsClient client = mAwContentsClient.get();
        if (client == null) return;
        String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl();
        boolean isErrorUrl =
                unreachableWebDataUrl != null && unreachableWebDataUrl.equals(failingUrl);
        if (isMainFrame && !isErrorUrl && errorCode == NetError.ERR_ABORTED) {
            // Need to call onPageFinished for backwards compatibility with the classic webview.
            // See also AwContents.IoThreadClientImpl.onReceivedError.
            client.getCallbackHelper().postOnPageFinished(failingUrl);
        }
    }

    @Override
    public void didStopLoading(String validatedUrl) {
        if (validatedUrl.length() == 0) validatedUrl = ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL;
            AwContentsClient client = getClientIfNeedToFireCallback(validatedUrl);
        if (client != null && validatedUrl.equals(mLastDidFinishLoadUrl)) {
            client.getCallbackHelper().postOnPageFinished(validatedUrl);
        mLastDidFinishLoadUrl = null;
        }
    }

我们可以很容易地看出,onPageFinished并不完全符合您的期望。

0
回答你的第一个问题:我发现onProgressChanged不会达到100,而且只有当该页面的所有资产(css/js/images)加载完成后,onPageFinished才会被调用。
然而,我找不到任何官方文件说明这一点。

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