关于shouldOverrideUrlLoading方法的一些考证

前言 

这周在做一个需求时,需要用到WebView,但是在做的过程中,却遇到了一些问题。WebView我其实接触并不多,这次的需求里还涉及了一些JS交互之类的,所以我是边学边做,但是网上的示例和教程,往往藏着一些坑,这一次我就发现关于shouldOverrideUrlLoading这个方法,网上的说法真的是五花八门,这篇文章,我们来澄清一下shouldOverrideUrlLoading的真正用法。


正文 
关于shouldOverrideUrlLoading用法的误解,主要还是集中在返回值上。 
错误说法1:返回true就调用系统浏览器,返回false由WebView处理。 
错误说法2:返回true当前url即使是重定向url也不会再执行,返回false由系统执行url,直到不再执行此方法。 
错误说法3:WebView上的所有加载都经过这个方法。 
错误说法4:这是一种广为流传的用法,在shouldOverrideUrlLoading中

@Override 
public boolean shouldOverrideUrlLoading(WebViewview, String url) { 
view.loadUrl(url); 
return true; 
} 

便可以在WebView中加载该url。 

那么我们来看看官方文档是怎么说的: /** 
* 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". 

* @param view The WebView that is initiating the callback. 
* @param url The url to be loaded. 
* @return True if the host application wants to leave the current WebView 
* and handle the url itself, otherwise return false. 
* @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest) 
* shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead. 
*/ 

大致翻译一下: 
若没有设置 WebViewClient 则由系统(Activity Manager)处理该 url,通常是使用浏览器打开或弹出浏览器选择对话框。 
若设置 WebViewClient 且该方法返回 true ,则说明由应用的代码处理该 url,WebView 不处理,也就是程序员自己做处理。 
若设置 WebViewClient 且该方法返回 false,则说明由 WebView 处理该 url,即用 WebView 加载该 url。 
 

所以上面的说法1和说法2都是错误的。对于说法4,直接返回false即可达到同样的效果。
至于说法3,我在断点调试的时候就已经发现不对了,并不会每次加载都走shouldOverrideUrlLoading,但是文档里并没有说shouldOverrideUrlLoading真正的调用时机是什么,所以我继续在网上查找,终于找到一篇源码分析,得出结论:
WebView的前进、后退、刷新、以及post请求都不会调用shouldOverrideUrlLoading方法,除去以上行为,还得满足( ! isLoadUrl || isRedirect) 即 (不是通过webView.loadUrl来加载的 或者 是重定向) 这个条件,才会调用shouldOverrideUrlLoading方法。
 

最后再补充一个知识点,关于shouldOverrideUrlLoading 和 onPageStarted 调用的先后顺序 (在会调用shouldOverrideUrlLoading 的情况下):


当我们点击页面中的一个Link时,先调用shouldOverrideUrlLoading再调用onPageStarted。 
当我们通过loadUrl的方式加载一个页面时,先调用onPageStarted再调用shouldOverrideUrlLoading。 

并不是我们通常理解的onPageStarted一定在前,shouldOverrideUrlLoading 一定在后。

结语 

通过这件事,让我在网上查找资料的时候更加谨慎了,因为已经不是第一次出现这种情况了。广为流传的错误答案,千篇一律的复制粘贴。这对于初学者来说,往往会造成严重的误导和困惑。所以我们在写东西的时候,也要更加慎重,不要把自己都没弄清楚的东西,当成结论发表出来,更不要不加思考的去复制粘贴别人的东西。理所应当的,本文中的结论,都是笔者在网上查资料,并且结合官方文档和源码,然后自己写程序验证过的,目的是为了让更多的初学者不被误导。当然了,人无完人,如果文中出现有误的地方,也欢迎大家指正。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值