11

I noticed that with the last update of Google System WebView, all the links in my WebViews are opened in the view itself. But according to the documentation from google:

public boolean shouldOverrideUrlLoading (WebView view, String url) Added in API level 1

Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url. This method is not called for requests using the POST "method".

I did not provide custom WebViewClient.

NOTE: The device that I noticed the problem was HTC One with the latest Google System WebView from June 8, 2015

Kamen Goranchev
  • 1,836
  • 1
  • 23
  • 27

2 Answers2

11

I can reproduce the findings. Android System WebView 43.0.2357.121 exhibits the behavior that you describe, while the version I had on before upgrading to it did not.

I have filed a bug report on this and now need to do more testing and warn the world.

Thanks for pointing this out!

UPDATE

Here is a blog post that I wrote on this subject. Quoting myself from it:

My recommendation at the moment is:

  • Always attach a WebViewClient to your WebView

  • Always implement shouldOverrideUrlLoading() on the WebViewClient

  • Always return true to indicate that you are handling the event

  • Always do what your app needs to have done, whether that is loading the URL into the WebView or launching a browser on the URL (rather than returning false and relying on stock behavior)

Something like this static inner class appears to do the trick — create an instance and pass it to setWebViewClient() on your WebView:

private static class URLHandler extends WebViewClient {
  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (shouldKeepInWebView(url)) {
      view.loadUrl(url);
    }
    else {
      Intent i=new Intent(Intent.ACTION_VIEW, Uri.parse(url))
          .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

      view.getContext().startActivity(i);
    }

    return(true);
  }

  private boolean shouldKeepInWebView(String url) {
    return(true); // or false, or use regex, or whatever
  }
}

(where you would put your business logic in shouldKeepInWebView() to determine whether or not a given URL should stay in the WebView or launch a browser)

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    out of curiosity and completely unrelated (sorry for that): any specific reason you're always writing `return(true)` instead if `return true`? Just a stylistic taste I suppose, but where does it come from? – futtetennista Jun 11 '15 at 21:32
  • 2
    @stefano: `return(true)` is old C/C++ syntax that was the convention in early Java development. See: http://stackoverflow.com/questions/4216723/function-return-writing-style-in-java IOW, I'm kickin' it old school, yo. – CommonsWare Jun 11 '15 at 21:44
  • I will be happy if you see my question about `webView` in https://stackoverflow.com/questions/63533432/how-can-we-load-a-url-after-a-base-url-loaded-in-webview/63534340#63534340 – milad salimi Aug 22 '20 at 09:11
0

Seems to me this issue was resolved in 44.0.240.54.

neatox
  • 1
  • 1
    Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Jun 19 '15 at 07:17