CheeseLemon
CheeseLemon

Reputation: 126

Android webview - shouldOverrideUrlLoading() not called in some jsp pages

I've been developing hybrid apps for many companies with mobile websites. And as a matter of fact, there are some websites made with using jsp.

I already had the knowledge that iframes and javascripts xhr requests will not fire webViewClient's shouldOverrideUrlLoading override function. I'm fine with that.

But today I learned that SOME actions such as:

will not ALWAYS fire this function.

Hence, shouldOverrideUrlLoading() does not fire, when the webView is asked to load a page that it cannot load(i.e. "intent://...",) it shows an error page.

Has anyone encountered this kind of behaviour and is there any solution to work around it ?

Below is the code I'm using to invoke activities, where urls with 'intent:' protocol (which will fail because this function never gets called when above actions are performed)

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // ... omitted ...
        if ( url.startsWith("intent:") ) {
            Intent intent = null;
            try {
                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
                // The following flags launch the app outside the current app
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                try {
                    getActivity().startActivity(intent);
                } catch (ActivityNotFoundException e) {
                    e.printStackTrace();
                }
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
            return true;
        }
}

ps. please notice that every other websites' page loads will perfectly call shouldOverrideUrlLoading(). I couldn't find any JSP related bugs on android webViews so I'm asking one.

ps. I am happily willing to provide sample websites that some gracious readers will try on.. but the website's written in Korean so I doubt it will help.

Thank you!

Upvotes: 1

Views: 1193

Answers (1)

Lynch Chen
Lynch Chen

Reputation: 308

Your problem might not related to JSP, the real problem may be shouldOverrideUrlLoading() itself. In this case, using shouldOverrideUrlLoading() may not be a good idea, so why not try another perspective?

  • I've encountered many problems when using shouldOverrideUrlLoading() loading XmlHttpRequest. At the end, I came up with the idea using onProgressChanged() and it solved all my problems. I've written a similar answer here.

I tried adding your code into my own webview project and tested it with some JSP sites, and looks like it always work. I also added loadUrl() after other activities are invoked, so after pressing the back button, the loading error page will not be displayed again. So try this one :

First declare a global variable to store last URL.

String strLastUrl = null;

Then override onProgressChanged(WebView view, int progress)

    mWebView.setWebChromeClient(new MyWebChromeClient(){
    
       @Override
       public void onProgressChanged(WebView view, int progress) {
                if (progress == 100) {
                    //A fully loaded url will come here
                    String StrNewUrl = view.getUrl();
                    if(TextUtils.equals(StrNewUrl,strLastUrl)){
                       //same page was reloaded, not doing anything
                    }else{
                       String strOldUrl = null;
                       //save old url to variable strOldUrl before overwriting it
                       strOldURL = strLastUrl;
                       //a new page was loaded,overwrite this new url to variable
                       strLastUrl = StrNewUrl;

                       if ( strLastUrl.startsWith("intent:") ) {
                           Log.d("TAG", "intent triggered");
                           Intent intent = null;
                           try {
                                intent = Intent.parseUri(strLastUrl, Intent.URI_INTENT_SCHEME);
                                // The following flags launch the app outside the current app
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                                try {
                                    startActivity(intent);
                                } catch (ActivityNotFoundException e) {
                                    e.printStackTrace();
                                }
                                //reload the page before invoking other activities
                                view.loadUrl(strOldURL);

                            } catch (URISyntaxException e) {
                                e.printStackTrace();
                            }

                        }

                    }
                }
                super.onProgressChanged(view, progress);
            }
    });

Upvotes: 0

Related Questions