周一,又跟大家见面了。今天这篇来自李政 投稿,并非长篇大论剖析WebView源码,而是针对页面跳转时的具体函数调用做了细致的实践分析。

李政 的博客地址:

简介

在实际项目开发中,我们用到WebView的场景,大多是在对接协议、第三方应用或网页时出现。对于页面加载,WebView没有自带等待效果。所以,需要我们去自定义各种带进度条的WebView,网上相关的例子也是不胜枚举,今天我们就来谈谈一条地址请求在WebView中的跳转问题:

WebView中有两个工具类负责管理网页各种行为:WebChromeClient和WebViewClient。分别通过setWebChromeClient()和setWebViewClient()来实例化。

WebChromeClient:

js跳转页面_js 跳转页面代码_js跳转到一个新页面

Chrome一词表明这个类和webView的网页内容管理有关,它的成员方法帮助WebView处理Javascript的弹框、网站图标、网站title、加载进度等。最常用的方法如下:

当网页出现上述操作时,便会触发方法。其中onProgressChanged()方法通常用来设计成线性进度条的样式。当然这个工具类不是本次内容的主角。

WebViewClient

WebViewClient(本篇重点):

js跳转页面_js跳转到一个新页面_js 跳转页面代码

js跳转到一个新页面_js跳转页面_js 跳转页面代码

帮助WebView处理各种通知、请求事件、记录页面加载过程的。其中就包括URL地址,我们可以通过它来监控到地址的调用过程。

我们需要用到的相关的方法有:

shouldOverrideUrlLoading():

js 跳转页面代码_js跳转到一个新页面_js跳转页面

onPageStarted():

js跳转页面_js跳转到一个新页面_js 跳转页面代码

onPageFinished():

js 跳转页面代码_js跳转页面_js跳转到一个新页面

网页加载分析

js跳转到一个新页面_js 跳转页面代码_js跳转页面

触发加载网页的行为主要有两种方式:

(A)点击页面,触发标签。

(B)调用WebView的loadUrl()方法。

这两种方法都会发出一条地址,区别就在于这条地址是目的地址还是重定向地址。

我们以访问百度的页面来测试一下方法的执行顺序。我事先在shouldOverrideUrlLoading(),onPageStarted(),onPageFinished()中添加的log输出,我们观察一下log日志:

1、在代码中通过loadUrl加载百度的首页,此时的行为属于(B)方式:

Log如下:

2、在首页,我们点击一下“hao123”,跳转到 的主页上来,此时的行为属于(A)方式,Log如下:

js跳转页面_js 跳转页面代码_js跳转到一个新页面

3、点击“影视”,进入到影视页面,此时的行为属于(A)方式,Log如下:

4、然后js跳转页面,我们点击“影视列表”,此时的行为属于(A)方式,Log如下:

5、我们重新发起一次loadUrl(),这次访问一下CSDN,此时的行为属于(B)方式,Log如下:

通过上述范例,我们可以得出以下结论:

在A行为方式(点击页面,触发标签)下:

1、如果是目的地址,那么方法的执行顺序是:

js 跳转页面代码_js跳转页面_js跳转到一个新页面

shouldOverrideUrlLoading()->onPageStarted()->onPageFinished()

shouldOverrideUrlLoading()由于它要提供给APP选择加载网页环境的机会,所以只要是网页上地址请求,都会获取到。

2、如果是重定向地址,在跳转到目的地址之前会进行不断的地址定位,每一次地址定位都会由以下执行顺序体现出来:

onPageStarted()->shouldOverrideUrlLoading()->onPageFinished()

我们暂且设定这种执行顺序叫:fixedposition

那么一个正常的重定向地址,方法的执行顺序就是:

shouldOverrideUrlLoading()->fixedposition->…->fixedposition->onPageStarted()->onPageFinished()

在B行为方式(调用WebView的loadUrl()方法)下:

1、如果是目的地址,那么方法的执行顺序是:

onPageStarted()->onPageFinished()

js 跳转页面代码_js跳转页面_js跳转到一个新页面

loadUrl()加载地址时,一般不会触发shouldOverrideUrlLoading()js跳转页面,一旦触发了,就说明这是一个重定向地址。

2、如果是重定向地址,方法的执行顺序就是:

fixedposition->…->fixedposition->onPageStarted()->onPageFinished()

何时显示进度条

综上,如果我们想要自定义进度条,就要考虑如何避免重定向行为造成的多次加载这种情况,(也许你的场景不需要这种保护)。我的解决方式是这样的:

设置一个Boolean全局变量flag

1、在onPageStarted()中设置为true,若加载样式没有开启,就开启进度条等加载样式。

2、在onPageFinished()中检测,如果为true,就说明已经是目的地址了,可以关闭加载样式了,如果是false,就不做处理,继续等待。

3、在shouldOverrideUrlLoading()中,设置为false,若加载样式没有开启,就开启进度条等加载样式

这样就可以很好的控制加载样式和网址跳转之间的关系了。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。