参考文献:
Webview基本用法:https://www.runoob.com/w3cnote/android-tutorial-webview.html
Webview重定向:https://blog.csdn.net/qq_41188773/article/details/89669354
shouldOverrideUrlLoading用法:https://blog.csdn.net/weixin_44221085/article/details/115795498?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.control&spm=1001.2101.3001.4242

一、基本概念
shouldOverrideUrlLoading(WebView view,String url)
作用:控制对新加载的Url的处理

onPageStared(WebView view,String url)
作用:通知主程序网页开始加载

onPageFinished(WebView view,String url,Bitmap favicon)
作用:通知主程序,网页加载完毕

二、回调顺序
一般情况下,webview打开一个页面时都会先回调onPageStared,但是通常会涉及到重定向问题更改加载的url。
所谓重定向,就是请求的url在webview进行识别时会发生改变,这里也涉及到前端的具体操作,就不赘述了,总之可以简单理解为真实的加载流程会改变多次初始url

实验代码:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        //......
        webView = (WebView)findViewById(R.id.webView1);
        mWebSettings = webView.getSettings();
        webView.loadUrl("https://www.baidu.cn");
        webView.setWebViewClient(new WebViewClient(){

            @Override
            public boolean shouldOverrideUrlLoading(WebView webView,String url){
                Log.d("加载url","shouldOverrideUrlLoading " + url);
                //webView.loadUrl(url);
                return false;
            }
            @Override
            public void onPageStarted(WebView webView, String url, Bitmap favicon){//Bitmap favicon:启动时加载的此页面的图标,如果已经存在于数据库
                super.onPageStarted(webView,url,favicon);
               // mProgressDialog.show();
                Log.d("开始加载","onPageStarted" + url);
            }
            @Override
            public void onPageFinished(WebView webView,String url){
                super.onPageFinished(webView,url);
                Log.d("结束加载","onPageFinished " + url);
            }
        });
    }

查看日志:
图片说明

如果把加载的url写为"https://www.baidu.com",日志的结果会是:
图片说明

可以看到尽管涉及了多次重定向,但是最终加载完成显示出来的url回调顺序一定是走的shouldOverrideUrlLoading → onPageStared → onPageFinished从而形成一个完整加载流程

三、shouldOverrideUrlLoading返回值ture/false的区别
如果不重写shouldOverrideUrlLoading,直接运行这一段的话

webView = (WebView)findViewById(R.id.webView1);
webView.loadUrl("https://www.baidu.com");

APP 会调用外部浏览器打开百度
由于shouldOverrideUrlLoading的默认返回值为false,但这里并不代表return true时就在app内打开网页,false就在浏览器打开!因为如果重写了shouldOverrideUrlLoading并返回false还是在app内打开url,说明返回值并不决定手否调浏览器加载url

        webView.setWebViewClient(new WebViewClient(){ 
//            @Override
//            public boolean shouldOverrideUrlLoading(WebView webView,String url){
//                Log.d("加载url","shouldOverrideUrlLoading " + url);
//                //webView.loadUrl(url);
//                return false;
//            }

甚至把重写的shouldOverrideUrlLoading注释掉, 只是将WebViewClient 设置成了当前获得的 WebView 的默认 WebViewClient,url还是会在当前app内的webview里打开

官方文档对webView.loadUrl的解释:
当一个URL即将被加载到当前的WebView中时,给主机应用程序一个控制的机会。如果没有提供WebViewClient,默认情况下,WebView会要求Activity Manager为URL选择合适的处理方式。

所以只要设置了自定义的WebViewClient,应用就会从默认调用外部浏览器打开网址变为默认在本地WebView上打开网址。与shouldOverrideUrlLoading的返回值根本无关。
只要提供了一个WebViewClient,返回值就表示是否阻止webview继续加载url,返回false,表示不进行阻止,webview会继续加载url;返回 true,webview会停止加载url。

实验:

@Override
            public boolean shouldOverrideUrlLoading(WebView webView,String url){
                Log.d("加载url","shouldOverrideUrlLoading " + url);
                return true;
            }

结果是webview未加载出网页,日志中显示:
图片说明

返回false的案例见上

四、引申
事实上这一机制的作用就在于可以防范一些不安全的url在app内打开,所以在重写shouldOverrideUrlLoading时,我们可以设计如果以http/https开头的url就return false;反之如果是 http/https以外的自定义url则调起浏览器处理并return true。