android 硬加速注意事项

来源:互联网 发布:零基础学算法第三版dvd 编辑:程序博客网 时间:2024/04/30 01:40

转载自:http://blog.csdn.net/niu_gao/article/details/7456222


当硬加速被启用,Android框架利用一个新的绘制模式来把你的应用呈现到屏幕,这个模式利用了一个显示列表.要完全理解显示列表以及它如何影响你的应用,先要理解android如何在非硬加速下绘制View.下面的小节描述了软加速的和硬加速的绘制models.

软件绘制模式

  在软件绘制模式,view按以下两步进行绘制:

  • 1使整个View层级都变得无效

  • 2绘制所有的View层级



  任何时候一个应用需要更新部分UI时,它应在任何改变了内容的View上调用invalidate()(或它的任一变体),使界面无效的消息在整个View层级中传播以计算应被绘制的屏幕区域(脏区域).之后Android系统绘任View层级中所有与脏区域有交集的View. 不幸的是,这种绘制模式有两个缺点:

  • 第一,这个模式需要在每个绘制路径中都执行很多代码.比如,如果你的应用在一个button上调用了invalidate()并且这个button位于另一个view之上,即使这个View没有变化,Android系统也会绘制这个View

  • 第二个问题是这个绘制模式可能隐藏你应用中的bug.因为Android系统会绘制与脏区域有交集的view,那么一个你改变了内容的view可能在没有被调用invalidate()时也会被重绘了.当这种情况发生时,你只能依赖那个需要重绘的view来获得正确的行为.但这个行为可能在你每次修改你的应用时都会改变.因此,在任何你修改了数据或状态而影响到绘制代码的时候,你总是应该在你的自定义view上调用invalidate()



  注:Androidview们会在它们的属性被改变时自动调用invalidate(),比如一个TextView的背景和文本改变时.

硬加速绘制模式

  Android系统依然使用invalidate()draw()来请求屏幕更新并画出views,但是对实际的绘制处理却不一样.现在不是在收到绘制命令立即执行了,而是Android系统把绘制命令记录到显示列表中,这个列表中包含了View层级的绘制代码的输出.另一个优化是Android系统只需为那些通过invalidate()标记为脏的View记录和更新显示列表.没有被invalidatedViews可以简单地使用先前的显示列表中的记录进行重绘.新的绘制模式包含三个阶段:

  • 1使整个View层级都无效

  • 2记录并更新显示列表

  • 3画显示列表



  使用此模式,你再不能依靠让View与脏区域交界而使它的draw()方法被调用.要保证Android系统记录下view的显示列表,你必须调用invalidate().忘记这样做会导致一个view总是一个模样,即使改变了它.但这是一个很容易被找出的bug



  使用显示列表还对提升动画性能有益,因为设置了某个属性,比如alpharotation等,不再需invalidating目标view(自动做了).这个优化也会应用到拥有显示列表的view(当你的应用被硬加速时的任何view).例如,假设有一个LinearLayout包含了一个ListView一个ButtonListView位于Button之上,LinearLayout的显示列表看起来如下:

  • DrawDisplayList(ListView)

  • DrawDisplayList(Button)

  假设现在你想改变ListViewopacity,在调用了ListViewsetAlpha(0.5f)后,显示列表现在包含如下项:

  • SaveLayerAlpha(0.5)

  • DrawDisplayList(ListView)

  • Restore

  • DrawDisplayList(Button)



  ListView复杂的绘制过程没有被执行,而是仅更新了更简单的LinearLayout的显示列表.如果在一个未硬加速的应用中,列表和它爹的绘制代码都会被重新执行.

不支持的绘制操作

  当启用了硬加速,2D呈现管道会支持通用的Canvas绘制操作,也支持不常用的操作.所有的绘制操作被用来呈现widgetslayouts以及通用高级视觉效果,比如反光和平铺纹理.下面的列表描述了已知的不能被硬加速支持的绘制操作:

  • Canvas

    • clipPath()

    • clipRegion()

    • drawPicture()

    • drawPosText()

    • drawTextOnPath()

    • drawVertices()

  • Paint

    • setLinearText()

    • setMaskFilter()

    • setRasterizer()



  另外,还有一些操作的行为在启用硬加速后会变得不一样:

  • Canvas

    • clipRect():异或,差异和反差异剪切都被忽略.3D变换不应用到剪切框中

    • drawBitmapMesh():颜色数组被忽略

    • drawLines():反锯齿不被支持

    • setDrawFilter():可以设置,但被忽略

  • Paint

    • setDither():被忽略

    • setFilterBitmap():滤镜一直启用

    • setShadowLayer():仅对文本起作用

  • ComposeShader

    • ComposeShader只能包含不同类型的着色器(比如一个BitmapShader和一个LinearGradient,不能是两个BitmapShader)

    • ComposeShader不能包含ComposeShader



  如果你的应用被这些缺少的特性或限制影响了,你可以通过调用setLayerType(View.LAYER_TYPE_SOFTWARE,null)为受影响的部分关闭硬加速.用此方法,你依然可以在其它地方享用到硬加速.


0 0
原创粉丝点击