解决在硬件加速下WebView切换闪屏的问题

转自:http://blog.csdn.net/so_huangbo/article/details/56286914

问题描述

在利用WebView进行开发时,遇到了这样一个问题,即在两个Fragment中分别嵌入两个WebView,切换Fragment时,页面会闪烁并伴随有黑块,用户体验非常糟糕。

解决历程

遇到问题,第一反应当然是百度了(现在国内的开发资料已经相当全面了,大多数的问题通过百度就可以解决,翻墙去Google比较麻烦)。通过关键词搜索,我得知这个bug是由于android的“硬件加速”引起的,何为硬件加速,即系统通过GPU来绘制图像,以牺牲内存为代价换取图像渲染的更加平滑,从Android 3.0开始支持使用硬件加速,Android 4.0开始默认开启。我这里只用一句话简单概括了一下,如果需要详细了解,可以查看这篇博文 Android——硬件加速(Hardware Acceleration)

既然问题的根源找到了,接下来就要知道怎么解决问题了。查询了很多资料博客,给出的解决方案都是一致的,手动关闭硬件加速。于是我照做,关闭后重新运行,Fragment切换果然顺畅了,没有出现闪屏,问题完美解决。如果你以为这样就结束了,那你就太年轻了,真正的难题才刚刚开始。闪烁的bug是解决了,但只要你细心,就会发现页面上下滚动的时候会卡顿,而之前开启硬件加速的时候是没有这个问题的。

这就难办了,硬件加速到底是应该开启还是关闭,这是个问题。我想,硬件加速是在Android 3.0之后新引入的,必然是Google对android系统做出的优化,而又在Android 4.0版本默认开启,充分说明了其重要性,所以肯定是不能关闭的。这样的话就又回到了起点的那个bug,怎么解决闪屏的问题。这里我反复搜索了很多信息,也有不少人遇到了同样的问题,但是都没有一个很好的解决方案,我甚至以为这是WebView的一个尚未解决的bug,不是我等区区几行代码就可以搞得定的。

后来我在一次偶然中发现,Fragment切换的时候,会走onAttach()和onDetach()等生命周期方法(这里我使用的是FragmentTabHost来控制Fragment的切换),为了验证我的猜测,我将代码进行重构,底部的导航按钮使用RadioButton,Activity初始化时加载所有Fragment,通过RadioButton来控制各个Fragment的hide()和show(),这样做的好处就是不会触发Fragment的任何生命周期方法。运行结果验证了我的猜想是正确的,之前使用FragmentTabHost来切换Fragment时会一次次地调用attach()和detach()方法,每一次切换,View都会进行一次重绘,这也就是在硬件加速下,导致WebView闪烁的罪魁祸首了。而改进过后的代码,虽然会一次性把所有的Fragment都加载进内存,加大了内存的消耗,但切换Fragment时不用对View进行重绘,恰好是解决这个bug的最佳方式。

既然了解了bug的产生原因,解决方案自然就不止一种。我们点开FragmentTabHost的源码,可以很明显地看到,doTabChanged()这个方法就是控制Fragment切换的核心逻辑。我们只要自定义一个MyFragmentTabHost,将源码复制进来,把所有的attach()和detach()方法改为show()和hide()就可以了。

自定义MyFragmentTabHost源码如下,可直接使用,

public class MyFragmentTabHost extends TabHost implements TabHost.OnTabChangeListener {
private final ArrayList

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值