关于安卓中的 shouldOverrideUrlLoading 方法的问题

public boolean shouldOverrideUrlLoading (WebView view, String url) 是一个在 WebViewClient 类中定义的方法,网上有的博客说该方法的作用是当返回值是 true 的时候控制 Url 在当前 WebView 打开,为 false 时调用系统浏览器或第三方浏览器打开。但实际上这种说法是错误的。

webView = (WebView) findViewById(R.id.webView);
        //WebView加载web资源
       webView.loadUrl("http://baidu.com");

当运行上面这段代码时,APP 会调用外部浏览器打开网页。
关于安卓中的 shouldOverrideUrlLoading 方法的问题

webView = (WebView) findViewById(R.id.webView);
        //WebView加载web资源
       webView.loadUrl("http://baidu.com");
        //覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开
       webView.setWebViewClient(new WebViewClient(){
           @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // TODO Auto-generated method stub
             view.loadUrl(url);
            return true;
        }
       });

当运行上面这段代码时,APP 会在内部的 WebView 中访问网址。
关于安卓中的 shouldOverrideUrlLoading 方法的问题

所以有人就认为是这段代码完成了这一个功能,并进一步推定当返回值是 true 的时候控制去 WebView 打开,为 false 调用系统浏览器或第三方浏览器。
**这就更大错特错了!**因为

webView = (WebView) findViewById(R.id.webView);
        //WebView加载web资源
       webView.loadUrl("http://baidu.com");
        //覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开
       webView.setWebViewClient(new WebViewClient(){
           @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // TODO Auto-generated method stub
             view.loadUrl(url);
            return false;
        }
       });

即将返回值从 true 改为 false,发现 APP 还是会在内部的 WebView 中访问网址。
关于安卓中的 shouldOverrideUrlLoading 方法的问题

更极端地:

webView = (WebView) findViewById(R.id.webView);
        //WebView加载web资源
       webView.loadUrl("http://baidu.com");
        //覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开
       webView.setWebViewClient(new WebViewClient());

根本没有重写这个方法,只是将一个新初始化的 WebViewClient 设置成了当前获得的 WebView 的默认 WebViewClient 而已,同样 APP 还是会在内部的 WebView 中访问网址。
关于安卓中的 shouldOverrideUrlLoading 方法的问题

所以 shouldOverrideUrlLoading (WebView view, String url) 方法根本不是这个功能,有些帖子纯粹是误人子弟。而只要设置了自定义的WebViewClient,应用就会从默认调用外部浏览器打开网址变为默认在本地WebView上打开网址。

查阅官方文档,其中关于 shouldOverrideUrlLoading 方法的使用是这样的

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if ("www.example.com".equals(Uri.parse(url).getHost())) {
                // This is my website, so do not override; let my WebView load the page
                return false;
            }
            // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(intent);
            return true;
        }
    }
    

在官方示例之前的代码中,已经设置了 WebView 的默认 WebViewClient 为上边定义的 MyWebViewClient,从该方法内部实现的功能可以看出该方法实际上在 webView.loadUrl() 方法执行时就会被自动调用,进行拦截处理操作。以下是官方的解释:

Give the host application a chance to take control when a URL is about to be loaded in 
the current WebView. If a WebViewClient is not provided, by default WebView will ask 
Activity Manager to choose the proper handler for the URL. If a WebViewClient is 
provided, returning true causes the current WebView to abort loading the URL, while 
returning false causes the WebView to continue loading the URL as usual.
当一个URL即将被加载到当前的WebView中时,给主机应用程序一个控制的机会。如果没
有提供WebViewClient,默认情况下,WebView会要求Activity Manager为URL选择合适的
处理方式。如果提供了一个WebViewClient,返回true会导致当前WebView中止加载
URL,而返回false会导致WebView继续像往常一样加载URL。

官方代码实现的功能是只有指定的网址才会在本应用 WebView 上直接打开(返回值为 false 表示不拦截,执行设置了 WebViewClient 后打开网址的默认操作),而不满足判断条件的其他网址会被重新定义访问方式(返回 true 会被拦截),最后会在外部浏览器中打开。之所以这么做是为了保障程序的安全性,不让一些陌生而危险的网站在应用内打开。

综上所述,当需要在 APP 页面中的 WebView 内打开网址的时候,只需设置 webView.setWebViewClient(new WebViewClient()) 就可以了。

上一篇:WebView下载文件并显示进度


下一篇:一个例子让我理解WebViewClient各方法重写的作用