目录
坑1:点击网页中的按钮无响应
坑2:WebView加载网页不显示图片
坑3:WebView加载网页中无法播放视频
坑4:WebView打开多个H5页面,返回键无效
坑5:android4.4以后webview默认不保存cookie状态
坑6:WebView 加载https 白屏以及重定向加载
坑7:Webview无法正常唤起系统相册来选择图片
坑8:WebView在可编辑状态下无法打开超链接
场景:两个H5页面,H1,H2,H2里面有一个按钮与JS交互,第一种情况:先进入H1页面,返回后在进入H2页面,点击按钮无响应,第二种情况:先进如H2页面,点击按钮正常,返回进入H1,在重新进入H2,点击无反应。
针对这种情况,发现导致以上这两种情况的原因是WebView属性设置错误导致的。
看了这几个属性的注释,恍然大悟,赶紧检查代码,果真如此,在H1页面的onPause()方法中设置了webView.onpauseTimers(),导致只要进入H1在返回就会调用这个属性,导致全局的WebView都无法响应。
android4.4以后google对http与https的安全认证方式进行了严格的区分,WebView默认不支持同时加载Https和Http混合模式。
在android4.4以前比如在webview里面播放视频是没有问题,比如优酷,腾讯视频都是正常播放,但是某天测试跟你反应腾讯视频不能播放了,然后你就懵逼了,明明之前是一直正常的为什么现在不行了,而且还是某些视频不能播放,这才是最骚的。作为一个有经验的程序猿应该第一反应到是android版本的兼容问题,没错这是google在4.4版本以后对http与https进行了安全认证的区分,4.4以后默认不支持https这种方式,但是google是提供向下兼容的所以提供了三种模式来适应不同的场景:
1、MIXED_CONTENT_NEVER_ALLOW:Webview不允许一个安全的站点(https)去加载非安全的站点内容(http),比如,https网页内容的图片是http链接。强烈建议App使用这种模式,因为这样更安全。
2、MIXED_CONTENT_ALWAYS_ALLOW:在这种模式下,WebView是可以在一个安全的站点(Https)里加载非安全的站点内容(Http),这是WebView最不安全的操作模式,尽可能地不要使用这种模式。
3、MIXED_CONTENT_COMPATIBILITY_MODE:在这种模式下,当涉及到混合式内容时,WebView会尝试去兼容最新Web浏览器的风格。一些不安全的内容(Http)能被加载到一个安全的站点上(Https),而其他类型的内容将会被阻塞。这些内容的类型是被允许加载还是被阻塞可能会随着版本的不同而改变,并没有明确的定义。这种模式主要用于在App里面不能控制内容的渲染,但是又希望在一个安全的环境下运行。
webView加载https的网页时,如果网页中的图片引用是http,Android5.0以上的手机webView默认不允许混合模式,https当中不能加载http资源,所以需要手动设置开启。
在webView所在Activity的AndroidManifest.xml中添加属性android:hardwareAccelerated="true"
设置WebView的webViewClient时,重写此方法
很多时候我们会在webview上进行第三方登录之类的需求,比如qq,微博之类的,但是在4.4以后
你会发现qq或者微博登录会在qq上显示授权登录成功但是webview上面却显示未登录状态,会存在一直登录不
上的现象,但是在4.4以前是正常的,这个也是因为android4.4以后google为了安全性的要求默认不保存cookie状态,
google也提供了API可以设置在4.4以后进行cookie保存,代码设置如下:记得判断版本
(转载自)
1.针对正常的webView 加载内核:
1-1. 启用mixed content
在Android5.0中,WebView方面做了些修改,如果你的系统target api为21以上:
系统默认禁止了mixed content和第三方cookie。可以使用setMixedContentMode() 和 setAcceptThirdPartyCookies()以分别启用。
系统现在可以智能选择HTML文档的portion来绘制。这种新特性可以减少内存footprint并改进性能。若要一次性渲染整个HTML文档,可以调用这个方法enableSlowWholeDocumentDraw()
如果你的app的target api低于21:系统允许mixed content和第三方cookie,并且总是一次性渲染整个HTML文档。
在使用WebView的类中添加如下代码:
1-2. 设置WebView接受所有网站的证书
在认证证书不被Android所接受的情况下,我们可以通过设置重写WebViewClient的onReceivedSslError方法在其中设置接受所有网站的证书来解决,具体代码如下:
//重写 onReceivedSslError 内的super 方法需要注释掉
2.针对腾讯TBS x5内核:
2-1.同样需要启用 mixed content,对于 html 页面内有https 和 http 图片混合的相关的连接地址,同样适用
引用x5 内核的相关引用
2-2:设置WebView接受所有网站的证书 同上 1-2
3.处理重定向的问题:
注意:有些网页需要支持Dom 存储(可处理部分白屏的问题)
按照API的说明 Sets whether the DOM storage API is enabled. The default value is false.
也就是是否开启本地DOM存储。应该是Html 5中的localStorage(可以使用Android4.4手机和Chrome Inspcet Device联调),用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的,绝大多数的浏览器都是支持 localStorage 的,但是鉴于它的安全特性(任何人都能读取到它,尽管有相应的限制,将敏感数据存储在这里依然不是明智之举),Android 默认是关闭该功能的。
因为页面内部,有图片地址连接 ,股票连接,等等,所有对相关的地址进行了拦截,我犯的错误是 重定向后显示的新连接 我没有进行处理。所以显示一直只加载中(白屏)。
对于 拦截到的url ,进行不同的处理,如果遇到重定向的页面特殊处理,我这里是重新跳转新的页面
IntentUtils.toWebshell(BaseDetailsWebviewActivity.this, url);
如果是当前页面 webView.load(url);也可以,针对不同情况自行处
解决问题之前我们先来说说上传文件的逻辑:当我们在Web页面上点击选择文件的控件()时,会回调下的(5.0及以上系统回调)。这个时候我们在方法中通过打开系统相册或者支持该的第三方应用来选择图片。like this:
最后我们在中将选择的图片内容通过的方法返回给,然后通过js上传。
是组件通过或者提供给我们的,它里面包含了一个或者一组,然后我们在里将传给的方法,这样就知道我们选择了什么文件。
低版本的回调方法是openFileChooser,5.0上将回调方法该为了。所以为了解决这一问题,兼容各个版本,我们需要对进行重载,同时针对5.0及以上系统提供方法:
中的包含了一组,所以针对5.0及以上系统,我们还需要对做一点点处理。
注意:做完了这些别忘了混淆
mSettings.setSupportMultipleWindows(true)是要在新窗口中打开网页;必须重写WebChromeClient的onCreateWindow方法。如果只在APP内部当前页直接打开,设置mSettings.setSupportMultipleWindows(false)就行了
setSupportMultipleWindows默认的是false,也就是说WebView默人不支持新窗口,但是这个不是说WebView不能打开多个页面了,只是你点击页面上的连接,当它的target属性是_blank时。它会在当前你所看到的页面继续加载那个连接。而不是重新打开一个窗口。
当你设置为true时,就代表你想要你的WebView支持多窗口,但是一旦设置为true,必须要重写WebChromeClient的onCreateWindow方法。
view
isDialog : 如果是true,代表这个新窗口只是个对话框,如果是false,则是一个整体的大小的窗口
isUserGesture
resultMsg
返回值:这个方法如果返回true,代表这个主机应用会创建一个新的窗口,否则应该返回fasle。如果你返回了false,但是依然发送resulMsg会导致一个未知的结果。
如果我们仅仅是将WebView嵌入我们自己的应用然后加载网页,很少有必要去设置支持多窗口。只在当前窗口加载新的网页就可。