[TOC]
前言
在Android 中内嵌H5是一种很常见的事情,但是有时候我们会遇到很多问题,现在说说我遇到的几个小问题。
H5无法加载,网页显示不完全,或者显示不完整。
{ //加载不显示页面处理方案
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webView.getSettings().setDomStorageEnabled(true);
}
在Android 5.0开始,WebView已经严格限制了加载不安全来源内容,有时候当前WebView加载很多不安全外部链接,WebView是不支持的,也就是显示空白页面或者显示不完整页面,一部分原因是H5页面内用引用了第三方东西,但是当我们无法控制来源内容的时候,我们可以加上 setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW) 这个表明,运行多种内容加载,包括当前安全源加载了不安全的内容。
当然这个一般是偶然的例外,如果H5端是自己公司的的并且能够控制内容,一般是可以内部解决的,还有一种情况也可能导致无法加载完成,就是如果H5采用了Storage 缓存一些判断数据,如果WebView没有开始缓存策略(注意这个是运行H5操作WebView进行缓存,而不是WebView缓存H5页面),可能导致H5逻辑判断失败,这时候需要加上 setDomStorageEnabled(true)
H5重定向导致goback无限循环
为了精确控制WeView的H5前进和后退,我们需要制定自己的后退操作点击,一般是返回上一步,外加完全退出。
其中完全退出,和返回上一步在正常访问都可以快速实现,借用 finish 和 goback Android功能,但是当有重定向的问题的时候,在IOS中和浏览器起可以正常返回,但是在Android WebView就形成了无限循环
1、首先我们了解下H5中几种重定向的方法
window.location.href
window.history.back
window.navigate
self.location
top.location
header url
可见并不是所以的重定向都会在Reponse中返回 window.location 也就我们无法通过访问返回的结果来判断是不是该URl是重新定向。 这种思路只能放弃
2、采用WebView的一些监听方法
监听WebView加载
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
WebView.HitTestResult hit = webView.getHitTestResult();
int hitType = hit == null ? WebView.HitTestResult.UNKNOWN_TYPE : hit.getType();
if (hitType != WebView.HitTestResult.UNKNOWN_TYPE) {
webView.loadUrl(url);
return true;
} else {
//重定向时hitType为0 ,执行默认的操作
return false;
}
}
}
这个是WebViewClient中的一个继承的方法
shouldOverrideUrlLoading 这个方法 在页面进行重定向会进行调用,但是这个并不是仅仅当重定向时候调用,当跳转或者加载非当前页面内容的时候(就是离开当前页面的很多操作),会加载JS或者html等很多链接,我们无法记录当前页面是否是重定向页面,并且也无法确定前面第几个步骤是重定向开始页面。
再翻找一下WebView的一些功能,我们可以看到WebView 提供了BackForWardList() 这个就是控制WebView 在前进和后退的堆栈。我尝试下打印堆栈中的链接
假如:A,B,C(其中A是原始页面,B是点击链接,C就是重载界面) 当我点击goback 程序会执行 C页面finish ->B 重载-> C结果堆栈内部打印还是 A,B,C 这样无限循环,虽然我们明明知道B链接重定向,最终加载C。但是我们还是无法解决一个问题,无法确定多个跳转那个是重定型链接。
我尝试打印 shouldOverrideUrlLoading url链接 当我点击goback
url为。B链接 -> 1,2,3,4(这里是指多个JS或者Html的跳转)->然后跳转到C链接,
这个有规律吗??这个真的没有规律吗??这个肯定有规律。 1、WebView 堆栈只会记录,重定向开始链接和重定向结束链接。 2、当我们点击goback 最终WebView会再次加载C链接,并且WebView History堆栈还是会记录B和C。 3、也就是说我们只要 点击goback B和C被清出堆栈,而又再次进入堆栈。
graph TD
A[A] -->|跳转| B(B)
C -->|goback| B[B]
B-->D{shouldOverrideUrlLoading}
D-->C[C]
也就是我们只要记录上次最终加载的Html然后载shouldOverrideUrlLoading进行判断就行了,如果上次加载最终链接是当前将要加载的链接,那么我们不进行加载并且,goBackOrForward()进行指定step出入堆栈,让重定向开始的B也结束掉,回到A即可,相当于我们也进行了重定向。这样就到达我们破解无限循环的目的了。