Search code examples
androidcordovawebviewandroid-webviewcordova-plugins

Android onOverrideUrlLoading based on javascript return value


I am working on a hybrid app and trying to return true or false in onOverrideUrlLoading of webview based on returned value from javascript function executed in webview

Example code I have so far.

//Have a boolean variable isExternalDomain; 
//Added JavascriptInterface webView.addJavascriptInterface(this, "android");

public boolean onOverrideUrlLoading(final String url) {


WebView.loadUrl("javascript:android.onData('true')");

//I Tried inserting sleep, delay EG: Thread.sleep(200); 


//I see the delay but still javascript executes last.

if(isExternalDomain) {
 return true;
 } else {
 return false;
 }

}

@JavascriptInterface public void onData(String value)
 {   
 isExternalDomain = true; 
}

So the Issue I am having is javascript execution happens after onOverrideUrlLoading completed executing all lines with isExternalDomain as false. I would like to have onOverrideUrlLoading returning true or false based on javascript returned value.


Solution

  • Unfortunately, running JavaScript code from inside onOverrideUrlLoading() isn't possible. You must return from onOverrideUrlLoading() before WebView can do anything else. When you call WebView.loadUrl() from inside onOverrideUrlLoading(), what really happens is an asynchronous task gets posted onto the WebView's message loop. It only gets processed after you leave onOverrideUrlLoading(). Thus, no amount of delay will make WebView to process your request while your code is inside onOverrideUrlLoading().

    If you want to prevent navigation from happening based on the decision made by JavaScript code, it's more natural to do that on the JavaScript side by using window.onbeforeunload event handler. If you return non-null value from it, an attempt to navigate away by clicking a link will be cancelled.

    Below is a sample of JavaScript code:

    window.onbeforeunload = function() {
        if (navigationDisallowed()) {
            return true;  // Prevent navigating away from the page.
        } else {
            return null;  // Allow navigating away.
        }
    }