转载:https://blog.csdn.net/u010217289/article/details/68065017
在实际项目开发中,我们用到WebView的场景,大多是在对接协议、第三方应用或网页时出现。
如果每次开启一个新的WebView页面使达到原生的返回效果,在需要到重定向的链接的时候就会出现中有个空白页面,该怎么解决,请看下面。
WebView中有两个工具类负责管理网页各种行为:WebChromeClient 和 WebViewClient。分别通过 setWebChromeClient() 和 setWebViewClient() 来实例化。
WebViewClient
WebViewClient(本篇重点):
帮助WebView处理各种通知、请求事件、记录页面加载过程的。 其中就包括URL地址,我们可以通过它来监控到地址的调用过程。
mWebView.setWebViewClient(webViewClient);
protected WebViewClient webViewClient = new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url);
}
public boolean shouldOverrideUrlLoading(WebView view, String
url) {
return false;//返回true表明点击网页里面的连接还是在当前的
webview里跳转,不跳到浏览器
}
};
我们需要用到的相关的方法有:
shouldOverrideUrlLoading():
onPageStarted():
onPageFinished();
我们测试一下方法的执行顺序。我事先在 shouldOverrideUrlLoading(),onPageStarted(),onPageFinished() 中添加的log输出,我们观察一下log日志:
1、 在代码中通过loadUrl加载百度的首页,此时的行为方式,Log如下:
03-29 15:30:06.514 9316-9316/com.china3s.strip E/测试: ====onPageStarted====
03-29 15:30:08.054 9316-9316/com.china3s.strip E/测试: ====onPageFinished====
2、我们点击一下网页中的按钮,跳转到其它的页面,此时的行为方式,Log如下:
03-29 15:56:31.094 9316-9316/com.china3s.strip E/测试: ====shouldOverrideUrlLoading====
03-29 15:56:31.294 9316-9316/com.china3s.strip E/测试: ====onPageStarted====
03-29 15:56:34.774 9316-9316/com.china3s.strip E/测试: ====onPageFinished====
3、我们点击一下网页中的按钮,跳转到其它的页面出现重定向的时候,此时的行为方式,Log如下:
03-29 15:57:19.654 9316-9316/com.china3s.strip E/测试: ====shouldOverrideUrlLoading====
03-29 15:57:19.954 9316-9316/com.china3s.strip E/测试: ====onPageStarted====
03-29 15:57:19.974 9316-9316/com.china3s.strip E/测试: ====shouldOverrideUrlLoading====
03-29 15:57:19.954 9316-9316/com.china3s.strip E/测试: ====onPageStarted====
03-29 15:57:21.274 9316-9316/com.china3s.strip E/测试: ====onPageFinished====
通过上述范例,我们可以得出以下结论:
1、如果是目的地址,那么方法的执行顺序是:
shouldOverrideUrlLoading() -> onPageStarted() -> onPageFinished()
shouldOverrideUrlLoading()由于它要提供给APP选择加载网页环境的机会,所以只要是网页上地址请求,都会获取 到。
2、如果是重定向地址,在跳转到目的地址之前会进行不断的地址定位,每一次地址定位都会由以下执行顺序体现出 来:
**onPageStarted()->shouldOverrideUrlLoading()->onPageFinished()**
我们暂且设定这种执行顺序叫:Redirect
那么一个正常的重定向地址,方法的执行顺序就是:
shouldOverrideUrlLoading()->Redirect -> … -> Redirect ->onPageStarted()->onPageFinished()
1、 如果是目的地址,那么方法的执行顺序是:
onPageStarted() -> onPageFinished()
loadUrl()加载地址时,一般不会触发shouldOverrideUrlLoading(),一旦触发了,就说明这是一个重定向地址。
2、 如果是重定向地址,方法的执行顺序就是:
Redirect -> … -> Redirect ->onPageStarted()->onPageFinished()
综上,如果我们想要自定义进度条,就要考虑如何避免重定向行为造成的多次加载这种情况,(也许你的场景不需要这种保护)。我的解决方式是这样的:
设置一个Boolean全局变量isRedirect;为是否是重定向。
设置一个Boolean全局变量isPageOk;为是否是加载完成。
1、在 onPageStarted() 中设置为isRedirect = true; isPageOk = false。
2、在 onPageFinished() 中检测,如果为isRedirect = true,就说明已经是目的地址了就把isPageOk = true;
3、在 shouldOverrideUrlLoading() 中,设置为isRedirect=false;
全部代码
boolean isRedirect = false; //是否是重定向
boolean isPageOk = false; //目的地地址加载完成
protected WebViewClient webViewClient = new WebViewClient() {
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // 接受所有网站的证书
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
isRedirect = true;
isPageOk = false;
Log.e("测试", "====onPageStarted====");
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
isPageOk = isRedirect;
Log.e("测试", "====onPageFinished====");
}
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.e("测试", "====shouldOverrideUrlLoading====");
isRedirect = false;
if (isPageOk) {
//页面跳转
return true;
}
return false;//返回true表明点击网页里面的连接还是在当前的webview里跳转,不跳到浏览器
}
};
————————————————
版权声明:本文为CSDN博主「落幕-无悔」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010217289/article/details/68065017
https://blog.csdn.net/yushanddddfenghailin/article/details/103975772