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