转自:微点阅读 https://www.weidianyuedu.com/
简介
在实际项目开发中,我们用到WebView的场景,大多是在对接协议、第三方应用或网页时出现。对于页面加载,WebView没有自带等待效果。所以,需要我们去自定义各种带进度条的WebView,网上相关的例子也是不胜枚举,今天我们就来谈谈一条地址请求在WebView中的跳转问题:
WebView中有两个工具类负责管理网页各种行为:WebChromeClient 和 WebViewClient。分别通过 setWebChromeClient() 和 setWebViewClient() 来实例化。
WebChromeClient:
Chrome一词表明这个类和webView的网页内容管理有关,它的成员方法帮助WebView处理Javascript的弹框、网站图标、网站title、加载进度等。最常用的方法如下:
onJsConfirm():页面选择框;
onJsAlert():页面提示框;
onJsPrompt():页面确认框;
onProgressChanged():加载进度;
当网页出现上述操作时,便会触发方法。其中 onProgressChanged() 方法通常用来设计成线性进度条的样式。当然这个工具类不是本次内容的主角。
WebViewClient
WebViewClient(本篇重点):
帮助WebView处理各种通知、请求事件、记录页面加载过程的。 其中就包括URL地址,我们可以通过它来监控到地址的调用过程。
我们需要用到的相关的方法有:
shouldOverrideUrlLoading():
onPageStarted():
onPageFinished():
网页加载分析
触发加载网页的行为主要有两种方式:
(A)点击页面,触发
(B)调用WebView的loadUrl()方法。
这两种方法都会发出一条地址,区别就在于这条地址是目的地址还是重定向地址。
我们以访问 http://www.baidu.com 百度的页面来测试一下方法的执行顺序。我事先在 shouldOverrideUrlLoading(),onPageStarted(),onPageFinished() 中添加的log输出,我们观察一下log日志:
1、 在代码中通过loadUrl加载百度的首页,此时的行为属于(B)方式:
Log如下:
2、在首页,我们点击一下“hao123”,跳转到 www.hao123.com 的主页上来,此时的行为属于(A)方式,Log如下:
3、点击“影视”,进入到影视页面,此时的行为属于(A)方式,Log如下:
4、然后,我们点击“影视列表”,此时的行为属于(A)方式,Log如下:
5、我们重新发起一次loadUrl(),这次访问一下CSDN,此时的行为属于(B)方式,Log如下:
通过上述范例,我们可以得出以下结论:
在A行为方式(点击页面,触发)下:
1、如果是目的地址,那么方法的执行顺序是:
shouldOverrideUrlLoading() -> onPageStarted() -> onPageFinished()
shouldOverrideUrlLoading()由于它要提供给APP选择加载网页环境的机会,所以只要是网页上地址请求,都会获取到。
2、如果是重定向地址,在跳转到目的地址之前会进行不断的地址定位,每一次地址定位都会由以下执行顺序体现出来:
onPageStarted()->shouldOverrideUrlLoading()->onPageFinished()
我们暂且设定这种执行顺序叫:fixed position
那么一个正常的重定向地址,方法的执行顺序就是:
shouldOverrideUrlLoading()->fixed position -> … -> fixed position ->onPageStarted()->onPageFinished()
在B行为方式(调用WebView的loadUrl()方法)下:
1、 如果是目的地址,那么方法的执行顺序是:
onPageStarted() -> onPageFinished()
loadUrl()加载地址时,一般不会触发shouldOverrideUrlLoading(),一旦触发了,就说明这是一个重定向地址。
2、 如果是重定向地址,方法的执行顺序就是:
fixed position -> … -> fixed position ->onPageStarted()->onPageFinished()
何时显示进度条
综上,如果我们想要自定义进度条,就要考虑如何避免重定向行为造成的多次加载这种情况,(也许你的场景不需要这种保护)。我的解决方式是这样的:
设置一个Boolean全局变量flag
1、在 onPageStarted() 中设置为true,若加载样式没有开启,就开启进度条等加载样式。
2、在 onPageFinished() 中检测,如果为true,就说明已经是目的地址了,可以关闭加载样式了,如果是false,就不做处理,继续等待。
3、在 shouldOverrideUrlLoading() 中,设置为false,若加载样式没有开启,就开启进度条等加载样式
这样就可以很好的控制加载样式和网址跳转之间的关系了。