WebViewClient not calling shouldOverrideUrlLoading

后端 未结 10 2349
逝去的感伤
逝去的感伤 2020-12-15 18:44

The problem is rather simple. In the application we want to keep track of the current url being displayed. For that we use shouldOverrideUrlLoading callback fr

相关标签:
10条回答
  • 2020-12-15 19:28

    onProgressChanged is always triggered when reloading, loading new page with userclick or XmlHttpRequest. Compare the URL of previous load and the current load, you'll know it's reloading or loading a new page. This works perfect in my single page Web App.

    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{
                       //a new page was loaded,write this new url to variable
                       strLastUrl = StrNewUrl;
                       //do your work here
                       Log.d("TAG", "A new page or xhr loaded, the new url is : " + strLastUrl);
                    }
                }
                super.onProgressChanged(view, progress);
            }
    });
    

    I've also tried above solutions, but most of them have issue in my case:

    1. doUpdateVisitedHistory sometimes can not return correct url after "#" made by XmlHttpRequest.
      • My case is a single page web App. The web App uses javascript with xhr to display new page when user click an item. For example, user is currently at http://example.com/myapp/index.php , after clicking, the browser url becomes http://example.com/myapp/index.php#/myapp/query.php?info=1, but in this case, doUpdateVisitedHistory returns http://example.com/myapp//myapp/
    2. onReceivedTitle doesn't work in my case because the response retrieved by XMLHttpRequest does not have <title></title> tag.
    3. The JavascriptInterface method also works, but I'm afraid it will cause security related issues with javascript.
    0 讨论(0)
  • 2020-12-15 19:32

    When you click a product on that web page, it loads the new content in with JavaScript and updates the visible URL in the address bar using the HTML5 History APIs.

    From the above MDN article:

    This will cause the URL bar to display http://mozilla.org/bar.html, but won't cause the browser to load bar.html or even check that bar.html exists.

    These are sometimes called single-page applications. Since the actual loaded page doesn’t change, the WebView callback for page loads isn’t called.

    In case you know precisely what kind of HTTP request you want to intercept, you could use the shouldInterceptRequest callback that gets called for each request. It’s likely that the web application loads some data from an API, for example when a product is shown, which you could then detect.

    If detecting this isn’t possible, but you’re in control of the web application, you could use the Android JavaScript interface to invoke methods within the Android application directly from the web page.

    If you’re not in control of the loaded page, you could still try to inject a local JavaScript file into the web page and observe when the history APIs are used, then call methods in your Android application over the JS interface. I tried observing these events in Chrome with the method described in the previous link and it seems to work fine.

    0 讨论(0)
  • 2020-12-15 19:32

    For me the problem was below line -

    mWebView.getSettings().setSupportMultipleWindows(true);
    

    After removing it shouldOverrideUrlLoading was being called.

    0 讨论(0)
  • 2020-12-15 19:33

    after stumbling on this problem and searching for solutions, I've found the one that worked perfectly for me

    https://stackoverflow.com/a/56395424/10506087

     override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
        // your code here
        super.doUpdateVisitedHistory(view, url, isReload)
    }
    
    0 讨论(0)
提交回复
热议问题