Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is considered onPageFinished in the Android WebViewClient?

I am trying to perform an action on an Android WebView after my webpage finishes loading in it. I setup my WebView to have a WebViewClient to make use of the onPageFinished event callback. However, after some testing, it does't seem to wait until all the JS on the page is done loading before my onPageFinished code fires.

The Google documentation says this:

public void onPageFinished (WebView view, String url)

Added in API level 1 Notify the host application that a page has finished loading. This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet. To get the notification for the new Picture, use onNewPicture(WebView, Picture).

Parameters

view The WebView that is initiating the callback.

url The url of the page.

1) Does onPageFinished only wait for the DOM to load?

2) Is there a way to detect when any JS on the page finishes? If so, what should I use?

I don't see anything in WebViewClient that would be for that purpose. I don't want to add a delay since my users can be on EDGE or on LTE.

like image 259
Steven Avatar asked Nov 20 '12 02:11

Steven


People also ask

What is Webviewclient in Android?

Android WebView is a system component for the Android operating system (OS) that allows Android apps to display content from the web directly inside an application.

How to inject JavaScript in WebView Android?

JavaScript is disabled in a WebView by default. You can enable it through the WebSettings attached to your WebView . You can retrieve WebSettings with getSettings() , then enable JavaScript with setJavaScriptEnabled() . WebView myWebView = (WebView) findViewById(R.

What is shouldOverrideUrlLoading?

shouldOverrideUrlLoading is called when a new page is about to be opened whereas shouldInterceptRequest is called each time a resource is loaded like a css file, a js file etc.


2 Answers

You need to implement the callbacks from WebChromeClient. The onPageFinished() is an API that is provided by WebViewClient. There is yet another interface named WebChromeClient that provides the progress information you are seeking:

http://developer.android.com/reference/android/webkit/WebChromeClient.html#onProgressChanged(android.webkit.WebView, int)

Open the link above and look for onProgressChanged(WebView view, int newProgress) - the 'newProgress' variable gives you the percentage of page load that was completed. When it reaches 100 you have a valid page. onPageFinished() cannot be reliably used for this (due to server side redirections etc)

I don't know what you mean by "when JS on the page is finished". Maybe you can clarify what you meant?

like image 163
vino Avatar answered Sep 20 '22 15:09

vino


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;
        }
    }

We can easily see that onPageFinished is not pretty much what you're expecting.

like image 21
Teng-pao Yu Avatar answered Sep 21 '22 15:09

Teng-pao Yu