Android 4.0以上的系统设置中的开发人员设置中有一项是“强制使用GPU渲染”。当这个开启时,可能会引起WebView的稳定,如页面加载后一闪而过又变成空白等。好在这一项默认是关闭的。
不过硬件加速确实会造成WebView容易出现问题,原来碰到过不少。但硬件加速确实有不少好处,可以大大加快客户端的速度,尤其是在播放动画的时候。最实惠的做法是整体打开硬件加速,然后根据实际场景使用setLayerType关闭WebView的硬件加速。
url拦截
Android WebView是拦截不到页面内的#fragment跳转的。但是url跳转的话,又会引起页面刷新,H5页面的体验又下降了。只能给WebView注入JS方法了。
不过IOS倒是可以拦截得到。
其它两个适配问题:
在WebView上面使用Animation,WebView的绘画区域不动。
WebView有时会出现某一块区域白屏的问题
可以参考这里:http://blog.csdn.net/a345017062/article/details/7478667
使用WebView不当可能会导致内存骤增,可以参考这里:
http://blog.csdn.net/a345017062/article/details/8518471
Android的WebView退出后flash视频播放器无法退出的问题
可以参考这里:http://blog.csdn.net/a345017062/article/details/6788502
Android 3.X中WebView使用Zoom控件程序崩溃的问题
http://blog.csdn.net/a345017062/article/details/6838449
1、硬件加速。Android 4.0以上的系统设置中的开发人员设置中有一项是“强制使用GPU渲染”。当这个开启时,在部分机型(我们在G14上发现这个问题)可能会引起WebView的稳定,如H5页面加载后一闪而过又变成空白等。强制调用隐藏方法setLayertype(software)也解决不了问题。后来发现如果把targetVersion设置为14及以上,这个问题可以解决。
2、跳转拦截。H5页面在使用window.location.href做地址跳转时,如果只是做#fragment跳转,shouldOverrideUrlLoading拦截不到。经过试验发现只能拦截到绝对地址、相对地址的跳转。另外,在2.3.7平台上面即使是使用location.href,window.location,self.location等,且待页面加载完1秒之后延迟调用也不能被拦截。终极方案还是使用JSBridge吧。
3、缓存模式。WebView的默认缓存模式是LOAD_DEFAULT,当设备离线时,WebView按照HTTP协议执行标准的网页缓存控制,有些已经过期,但仍在缓存中的网页,就显示不出来了。如果loadUrl时判断当前网络状态,发现设备离线时,把缓存模式设置为LOAD_CACHE_ELSE_NETWORK,就能做到设备离线时无论网页是否过期,只要被缓存了,都可以显示出来。显示过期网页总比显示错误页面要好一些。
4、清除缓存。WebView的缓存目录在2.X和4.X中不一样,会影响到清除缓存。目前来看使用的是toLowerCase().indexOf("webviewcache")>=0来判断是否webview的缓存目录还是比较靠谱的。
5、调用周期。onPageStarted、onPageFinished、onReceivedError这三个周期方法在网络发生错误时就不可靠了,会出现重复调用的问题。
6、appCache默认关闭,需要手动打开并进行设置。一般要求设置5M。
7、清除Cookie的操作是Application范围内的,需要注意这个可能引起的问题。
8、有一次WebView被destroy时调用了setWebViewClient(null); ,但在测试中发现会报空指针。(samsung i9220 Android 4.0.4 )
补充于2013.3.18
1、初次加载JS无法获取窗口尺寸。解决方案:先load一个空页面,再load真实地址。
2、给WebView设置padding无效。
3、WebView上面如果被其它View完全盖住的话,在刷新时,可能会出现闪屏的问题,即,加载成功后又迅速地刷了次。
补充于2013.3.28
不要轻易修改WebView的UA,这会在某些情况下降低用户体验。现在大部分网站都对浏览器的UA做判断,根据UA是手机还是PC来返回对应的页面版本,如果我们修改的UA网站无法识别的话,网站很可能就会把PC页面扔过来。
补充于2014.1.14
Android上面有一个经常会在线上Crash中发现的非必现异常:SQLiteException
这个异常不少人在使用WebView的时候碰到过,它非必现,概率不高,你通常会在线上Crash报告中才会发现它。原因众说纷纭。 这里给两个触发场景:
1、SQLite为了保护db文件一致性,当访问db文件时,会给文件上一个进程锁,这种情况下,如果有另外一个进程再访问这个db文件,就会出错了。 所以,你肯定想到了,你的APK如果满足以下两个条件会触发这个异常: 1、使用了WebView 2、使用了多个进程。 因为WebView会把Cache写到db文件中,肯定会涉及到db操作,这个操作是Application范围的。当使用多进程时,存在不同进程的WebView对同一个db文件进程操作的可能性,异常就会时不时出来了。
最后,按照Android老码农一惯的风格,当然要给出解决方案: 重写Application.openOrCreateDatabase,让不同的进程创建不同的db文件就好了。
2、CookieSyncManager在强制同步Cookie时也会出现SQLite IO的异常。所以强制同步需要谨慎使用。如果不涉及多进程共享Cookie,最好不要自己强制同步。