Android中WebView使用LoadUrl不刷新网页的问题,网址带#只能通过reload刷新

Posted wodongx123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中WebView使用LoadUrl不刷新网页的问题,网址带#只能通过reload刷新相关的知识,希望对你有一定的参考价值。

文章目录


可以直接快进到结论部分

项目场景:

最近在和其他公司沟通联调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无法重刷网页,问题就在于这两个方法的差别了。

经过一阵百度(因为WebView的一部分源码在AOSP里面,公司环境不好搞所以没有看源码),得知了真正原因是因为对方的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是无视缓存策略强制刷新的,所以我们拿这个地址去浏览器运行,是可以正常刷新的。

结论

  1. url中#以及后面的部分只是用于客户端定位,不会发给服务端
  2. 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

以上是关于Android中WebView使用LoadUrl不刷新网页的问题,网址带#只能通过reload刷新的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 的 WebView 中使用 LoadUrl 用页眉和页脚包装内容

当我使用 WebView loadUrl 函数时,Android Studio 应用程序被强制关闭

Android Webview - 使用一个 loadUrl 缩放图像以正确适合屏幕

android中webview loadUrl(String url,Map header)方法和postUrl(String url,byte[] postData)方法同时使用问题;

Android webview在调用loadurl时启动浏览器

如何给android的webview增添方法