onPageFinished is firing before page is loaded

It happened to me also, that in WebViewClient, the callback onPageFinished kicks in before the actual window.load event.

Still investigating on why this happens sometimes, which is hard because the android app is produced by a heavily customized in-house hybrid app generator.

Nevertheless, I've got past this issue by implementing a safeguard that checks if there is an error in the script that I want to call in onPageFinished, in which case I add an event handler which calls again my script during window.load.

You can also use document.addEventListener("DOMContentLoaded", ...) instead of window.load.

Below is a code snippet that exemplifies this, also with debug.log calls. You can pass the call to your javascript interface as argument

 private void executeOnLoad(final WebView view, final String jsStringToExecute) {
            StringBuilder sb = new StringBuilder("javascript:");
            sb.append("try {console.log('native.onPageFinished. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("} catch(err){console.log('error calling jsBridge script on page load, deferring call to window.load event');")
            .append("window.addEventListener('load', function() {console.log('window.onload callled from native. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("});").append("}");
            String jsWithWindowLoadedFallback = sb.toString();
            view.loadUrl(jsWithWindowLoadedFallback);
        }

Found simple technique to load page even after onPageFinished is called-- Recursively call loadUrl method until page is not loaded successfully.. @Override public void onPageFinished(WebView view, String url) { // progressDialog.hide();

              Log.e("onPageFinished","onPageFinished");
              if (view.getContentHeight() == 0){
                  pbar.setVisibility(View.VISIBLE);
                  webView.loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url="+pdf);

              }
              else {
                  pbar.setVisibility(View.GONE);
              }
          }

This is because onPageFinished means "the page has finished loading", not "the page is on screen". Unfortunately the WebView doesn't have a 'the page you wanted is now on screen' API. Folks usually resort to a combination of PictureListener (which was deprecated since it's unreliable) and random timeouts (which are either super long or don't work on some devices).

You could try by rendering to a small bitmap and checking if it's all white on every PictureListener callback (and remember to stop doing this when you're done waiting, otherwise you'll burn tons of CPU if the page has animations/gifs/etc..). Rendering to a small bitmap will still be very CPU-intensive if the page has big images, so this is definitely not a great solution.