Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is default behavior of Android's WebView changed to open internally all links?

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

like image 691
Kamen Goranchev Avatar asked Jun 11 '15 15:06

Kamen Goranchev


1 Answers

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)

like image 198
CommonsWare Avatar answered Sep 30 '22 20:09

CommonsWare