最近在和其他公司沟通联调H5的时候,意外发现对方发过来的地址可以加载,但是没有办法正常刷新。
写了个一个X5内核的demo,然后在WebViewClient的所有方法加上日志来监控对方网页的运行情况。
此处测试网址为https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa,是我随便写的。
对网页第一次加载可以正常加载(即调用了onPageStarted和onPagefinished)。
I/MyWebView: shouldInterceptRequest: https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa
I/MyWebView: onProgressChanged: 10
I/MyWebView: shouldOverrideUrlLoading: url:https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa
I/MyWebView: onPageStarted: url:https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa, favicon :null
............省略中间无关日志.........
I/MyWebView: onPageFinished: url:https://www.baidu.com/#
I/MyWebView: onProgressChanged: 70
I/MyWebView: onProgressChanged: 100
第二次调用loadUrl()加载的时候只会刷新图标,不会真的重新加载网页(只调用onPageFinished)。
I/MyWebView: onProgressChanged: 10
I/MyWebView: doUpdateVisitedHistory: url:https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa, isReload:false
I/MyWebView: onPageFinished: url:https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa
I/MyWebView: onProgressChanged: 100
I/MyWebView: shouldOverrideUrlLoading: url:https://sm.bdimg.com/static/wiseindex/img/favicon64.ico
最后意外发现当我们第二次加载对方的网页的时候,如果调用的是webView.loadUrl(url),就无法刷新,但是如果调用的是webView.reload(),就可以正常刷新对方的网页。
调用relaod时日志如下:
I/MyWebView: onProgressChanged: 10
I/MyWebView: shouldInterceptRequest: url:https://www.baidu.com/#
I/MyWebView: shouldOverrideUrlLoading: url:https://www.baidu.com/#
I/MyWebView: onPageStarted: url:https://www.baidu.com/#, favicon :android.graphics.Bitmap@a1689fc
I/MyWebView: onProgressChanged: 23
............省略中间无关日志.........
I/MyWebView: onProgressChanged: 100
I/MyWebView: onPageFinished: url:https://www.baidu.com/#
知道了调用reload可以重刷网页,调用loadUrl无法重刷网页,问题就在于这两个方法的差别了。
经过一阵百度,得知了真正原因是因为对方的URL带了#,所以导致loadUrl不会刷新网页。
将网址改为https://www.baidu.com/aaaaaaaaaaaaaaaaaaaa,再次调用loadUrl,第二次加载日志如下:
注:由于该网页并不存在,所以报404了,我们只是通过日志观察网页是否有重新加载而已。
I/MyWebView: shouldInterceptRequest: url:https://www.baidu.com/aaaaaaaaaaaaaaaaaaaa
I/MyWebView: onProgressChanged: 10
I/MyWebView: onReceivedHttpError: request https://www.baidu.com/aaaaaaaaaaaaaaaaaaaa
error: 404
I/MyWebView: onPageStarted: url:https://www.baidu.com/aaaaaaaaaaaaaaaaaaaa, favicon :android.graphics.Bitmap@1d36963
I/MyWebView: onProgressChanged: 70
I/MyWebView: onProgressChanged: 100
I/MyWebView: onProgressChanged: 100
I/MyWebView: onPageFinished: url:https://www.baidu.com/aaaaaaaaaaaaaaaaaaaa
可以看到有正常执行onPageStarted和onPageFinished
那么为什么URL里面带了个#,我们的WebView就无法通过loadUrl刷新网页了呢?
简单来说,URL中#以及其后面的部分,是客户端这边的位置定位符,在加载网页的时候并不会真正的发送给服务端。
其证明就是:我们的两个测试网址都是实际不存在的,但是带#的网址可以正常的加载出百度的首页,而没有带#的网址就直接报404了。
我们在用https://www.baidu.com/#/aaaaaaaaaaaaaaaaaaaa加载网页的时候,实际上发出的请求还是https://www.baidu.com/
当#后的内容修改的时候,也不会重新刷新页面,只是会修改网页内部的位置。
我们的测试网址由于带有#,所以无论怎么调用loadUrl,他都判断我们只是改变了网页内部的相对位置(虽然实际上我们并没有改变),不会重新加载这个网页,只是加载网页图标。
那为什么webViewreload又可以重刷网页呢,实际上是因为loadUrl默认会有缓存策略,而reload是无视缓存策略强制刷新的,所以我们拿这个地址去浏览器运行,是可以正常刷新的。
URL中#号的含义 - wanghetao - 博客园
https://www.cnblogs.com/wanghetao/p/3830467.html
关于安卓webview的loadUrl和reload方法缓存策略的区别发现记录_小源子2016的博客-CSDN博客
https://blog.csdn.net/rnZuoZuo/article/details/52327436?locationNum=11
webview第二次加载带#的url 调用loadUrl()不会刷新的坑__陈泡泡的博客-CSDN博客_webview loadurl数据不刷新
https://blog.csdn.net/weixin_42863849/article/details/122846830