Android layer type与WebView白屏以及WebView不随动画而动的问题

转自:

http://blog.csdn.net/a345017062/article/details/7478667

问题:WebView白屏(有数据)

报错:<spanheiti sc="" light'"="">[ERROR:in_process_view_renderer.cc(189)] Failed to request GL process. Deadlock likely: 0

解决:WebView设置setLayerType(View.LAYER_TYPE_SOFTWARE,null)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
分析: WebView 继承View,View中有三种layer type分别为

    /**
     * Indicates that the view does not have a layer.
     *
     * @see #getLayerType()
     * @see #setLayerType(int, android.graphics.Paint)
     * @see #LAYER_TYPE_SOFTWARE
     * @see #LAYER_TYPE_HARDWARE
     */
    public static final int LAYER_TYPE_NONE = 0;

    /**
     * <p>Indicates that the view has a software layer. A software layer is backed
     * by a bitmap and causes the view to be rendered using Android's software
     * rendering pipeline, even if hardware acceleration is enabled.</p>
     *
     * <p>Software layers have various usages:</p>
     * <p>When the <a target=_blank href="http://www.codes51.com/article/search_Application/" target="_blank" style="color: rgb(0, 0, 0); text-decoration: none;"><strong>Application</strong></a> is not using hardware acceleration, a software layer
     * is useful to apply a specific color filter and/or blending mode and/or
     * translucency to a view and all its children.</p>
     * <p>When the <a target=_blank href="http://www.codes51.com/article/search_Application/" target="_blank" style="color: rgb(0, 0, 0); text-decoration: none;"><strong>Application</strong></a> is using hardware acceleration, a software layer
     * is useful to render drawing primitives not supported by the hardware
     * accelerated pipeline. It can also be used to cache a complex view tree
     * into a texture and reduce the complexity of drawing operations. For instance,
     * when animating a complex view tree with a <span id="11_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="11_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=translation&k0=translation&kdi0=0&luki=4&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="11" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">translation</span></a></span>, a software layer can
     * be used to render the view tree <span id="12_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="12_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=only&k0=only&kdi0=0&luki=3&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="12" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">only</span></a></span> once.</p>
     * <p>Software layers should be avoided when the affected view tree updates
     * often. Every update will <a target=_blank href="http://www.codes51.com/article/search_require/" target="_blank" style="color: rgb(0, 0, 0); text-decoration: none;"><strong>require</strong></a> to re-render the software layer, which can
     * potentially be slow (particularly when <span id="5_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="5_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=hardware&k0=hardware&kdi0=0&luki=7&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="5" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">hardware</span></a></span> acceleration is turned on
     * since the layer will have to be uploaded into a hardware texture after every
     * update.)</p>
     *
     * @see #getLayerType()
     * @see #setLayerType(int, android.graphics.Paint)
     * @see #LAYER_TYPE_NONE
     * @see #LAYER_TYPE_HARDWARE
     */
    public static final int LAYER_TYPE_SOFTWARE = 1;

    /**
     * <p>Indicates that the view has a <span id="6_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="6_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=hardware&k0=hardware&kdi0=0&luki=7&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="6" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">hardware</span></a></span> layer. A hardware layer is backed
     * by a hardware specific texture (generally Frame Buffer Objects or FBO on
     * OpenGL hardware) and causes the view to be rendered using Android's hardware
     * rendering pipeline, but <span id="7_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="7_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=only&k0=only&kdi0=0&luki=3&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="7" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">only</span></a></span> if hardware acceleration is turned on for the
     * view hierarchy. When hardware acceleration is turned off, hardware layers
     * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
     *
     * <p>A <span id="8_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="8_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=hardware&k0=hardware&kdi0=0&luki=7&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="8" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">hardware</span></a></span> layer is useful to apply a specific color filter and/or
     * blending mode and/or translucency to a view and all its children.</p>
     * <p>A hardware layer can be used to cache a complex view tree into a
     * texture and reduce the complexity of drawing operations. For instance,
     * when animating a complex view tree with a <span id="9_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="9_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=translation&k0=translation&kdi0=0&luki=4&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="9" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">translation</span></a></span>, a hardware layer can
     * be used to render the view tree <span id="10_nwp" style="width: auto; height: auto; float: none;"><a target=_blank id="10_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=19&is_app=0&jk=cef02009fbfa4ac9&k=only&k0=only&kdi0=0&luki=3&mcpm=0&n=10&p=baidu&q=85048100_cpr&rb=0&rs=1&seller_id=1&sid=c94afafb920f0ce&ssp2=1&stid=9&t=tpclicked3_hc&td=1797308&tu=u1797308&u=http%3A%2F%2Fwww%2Ecodes51%2Ecom%2Farticle%2Fdetail%5F178654%2Ehtml&urlid=0" target="_blank" mpid="10" style="color: rgb(0, 0, 0); text-decoration: none;"><span style="color: rgb(0, 0, 255); width: auto; height: auto;">only</span></a></span> once.</p>
     * <p>A hardware layer can also be used to increase the rendering quality when
     * rotation transformations are applied on a view. It can also be used to
     * prevent potential clipping issues when applying 3D transforms on a view.</p>
     *
     * @see #getLayerType()
     * @see #setLayerType(int, android.graphics.Paint)
     * @see #LAYER_TYPE_NONE
     * @see #LAYER_TYPE_SOFTWARE
     */
    public static final int LAYER_TYPE_HARDWARE = 2;


LAYER_TYPE_NONE:表明视图没有多余渲染层。

LAYER_TYPE_SOFTWARE:表明视图有一个软件渲染层。无论是否开启硬件加速,都会有一张Bitmap(software layer),并在上面对WebView进行渲染。

好处:在进行动画,使用software可以只画一次View树,很省。

什么时候不要用:

View树经常更新时不要用。尤其是在硬件加速打开时,每次更新消耗的时间更多。因为渲染完这张Bitmap后还需要再把这张Bitmap渲染到hardware layer上面去。

LAYER_TYPE_HARDWARE:

表明视图有一个硬件渲染层。硬件加速关闭时,作用同software。硬件加速打开时会在FBO(Framebuffer Object)上做渲染,在进行动画时,View树也只需要画一次。

两者区别:

1.一个是渲染到Bitmap,一个是渲染到FB上。

2.hardware可能会有一些操作不支持(出现白屏)

两者相同:

都是开了一个buffer,把View画到这个buffer上面去。

PS:GLSurfaceView和WebView默认LayerType都是NONE。


GLSurfaceView:给GLSurfaceView设置为software或者hardware后,发现什么也画不出来了。得出结论:GLSurfaceView的LayerType只能是NONE。


WebView

以前使用WebView时碰到过一个问题,如果在WebView上面使用Animation,WebView的绘画区域不动。当时的解决方案是在进行动画之前对WebView进行截屏(drawingcache)。按上面的道理试了一下,设置一个hardware或者software的layer就OK了。

现在又碰到了另外一个问题,打开硬件加速后,在一些机器上面(我的是3.2及HTC 4.4)WebView有时会出现某一块区域白屏的问题。默认的LayerType是NONE,改为hardware也不行,设置为software就解决了。当然关闭硬件加速也好了,可是那样的话程序整体就比较慢了。所以最终方案是整体硬件加速,出问题的WebView设置software。


补充1:

加上这一句,可以让3D的绘制更快一些:getHolder().setType(SurfaceHolder.SURFACE_TYPE_HARDWARE);

补充2:

问题:

在硬件加速开启的情况下GLSurfaceView一旦被从View树上摘下来,会使整个窗口背景变黑,即使设置LayerType为software也不管用。

经过两天的排查,发现了原因,我的程序是在C层由drawFrame(属于GLThread线程)来驱动进行绘画,当时GLSurfaceView被摘下来时,GLSurfaceView的destroy方法被调用,我在destory方法(属于UI线程)中直接调用了GLThread线程的结束方法。而GLSurfaceView.creat, sizeChanged,destroyed在UI线程,Render.create,sizeChanged,drawFrame在GLThread线程。因此,出现了UI线程直接调用GLThread线程的方法问题。最终通过GLSurfaceView.queueEvent向GLThread线程发送Runnable,问题得到解决。

看来,还是软渲染的容错能力比较强,一开硬件加速,底层就比较脆弱了。

结论:一定要搞清楚哪个是UI线程,哪个是GLThread线程。


补充以上寻找问题过程中发现的知识点:

hardware acclerator是对整个窗口进行加速,在硬件加速打开时View.isHardwareAcclerator返回true。但每个View可能被渲染到的Canvas是不同的,比如View可能被通过setLayer设置layer,这时,Canvas.isHardwareAccelerator返回false

Android提供了三种硬件加速是否开启的控制级别,分别是Application,Activity,Window,View。这个可以参考DevGuide。


以上就介绍了Android layer type与WebView白屏以及WebView不随动画而动的问题,包括了方面的内容,希望对Android开发有兴趣的朋友有所帮助。

本文网址链接:http://www.codes51.com/article/detail_178654.html



你可能感兴趣的:(Android layer type与WebView白屏以及WebView不随动画而动的问题)