文档介绍:
Android4.0 的图形硬件加速及绘制技巧最牛傻蛋的博客 1.Android 4.0 硬件加速的使用 1.1 硬件加速的控制级别启用硬件加速的最简单方法就是为整个系统打开硬件加速的全局设置。如果你的程序是标准 View 或者是 Drawable 则硬件加速的全局设这并不会造成不良的影响。然而硬件加速并不支持所有 2D 画的操作,所以开启硬件加速可能会对使用自定义组件的应用程序造成影响, 问题常常表现在不可见的元素异常和错误的像素渲染, 为了解决这个问题 Android 可以让你选择启动或者禁用以下级别的硬件加速: Application Activity Window 和 View 。 1.1.1 Application 级别在你的 Android Manifest 文件中添加属性标记, 以便为整个应用程序使用硬件加速。 1.1.2 Activity 级别如果你的应用程序不能在 Application 应用级别表现良好的话, 则可以使用对 Activity 进行单独控制。要启动或者禁用一个 Activity 的硬件加速,你可以使用 activity 的 android:elerate d 属性。下面的一个列子使整个 Application 启用硬件加速, 但是对一个 Activity 禁止使用硬件加速。 1.1.3 Window 级别如果你需要更细粒度的控制,你可以通过如下代码给 window 进行加速。 getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDW ELERATED, WindowManager.LayoutParams.ELERATED); 注意:现阶段你不能在 Window 级别对它禁用硬件加速。 1.1.4 View 级别我们可以对单独的 View 在运行时阶段禁用硬件加速。我们可以使用如下代码: myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 注意: 现阶段不能够在 View 级别进行硬件加速。 1.2 判断一个 View 是否已经启用了硬件加速有时候我们需要知道一个应用程序是否已经启用了硬件加速, 特别是针对一些自定义控件。因为你的应用程序做了很多自定义“画”的操作,但并不是所有的过程都支持新的“画”的渲染过程。有两种不同的方法来检查 Application 是否启用了硬件加速: 1.2.1 使用 View.elerated() 如果返回 true 则可以说明这个 View 所在的窗口已经启用了硬件加速。 1.2.2 Canvas.elerated() 如果返回 tru e 则说明这个 Canvas 已经启用了硬件加速。如果你必须要在你的绘画代码中进行是否已经加速的检查, 如果可能的话请使用 Canvas.elerated() 来代替 View.elerated() 。当一个 View 是存在于一个已经加速的 Windows 上时, 任然可以使用没有硬件加速的 Canvas 进行绘画, 这场发生在, 比如, 当我们把一个 View 画到 Bitmap 上然后用作缓存。 2.Android 4.0 的绘制模型当开启了硬件加速, Android 框架将会使用一种新的绘制模型, 这种模型将会使用显示列表把你的应用显示到屏幕上。要完全理解显示列表和他们如何影响你的应用程序, 理解 Android 4.0 如何在非硬件加速的情况下如何绘制 Views 是很有必要的, 下面将分别介绍软件加速和硬件加速。 2.1 基于软件的绘制模型在基于软件绘制模型中, View 的绘制遵循以下两步: 1. 使整个控件层级无效。 2. 对层级进行绘制。当一个应用程序需要更新它 UI 的一部分时,它将会调用内容发生改变的 View 的 invalidate() 方法( 或者 invalidate 的变体)。 Invalidat e 的消息按照 Vie w 的层级关系向上传递用以计算需要重画的部分( 即脏区域) 。然后 Android 系统会对和脏区域有交集的所有 View 进行绘制,不幸的是这种模型中有两个缺点: 2.1.1 在这种模型中当在不同的层进行画的时候, 会额外执行很多代码。例如一个 Button 是位于另外一个 View 之上,当对 Button 调用 Invalidate() 时, Android 就会对这个 View 进行重绘, 即便这个 Vie w 没有发生任何变化。 2.1.2 第二个问题是这种绘制模型会隐藏你 Application 中的 Bug 。因为 Android 系统会对和脏区域有交集的 View 进行重绘,在这种情况下如果一个 vie w 的内容发生了改变, 即便这个 Vie w的 Invalidate() 的方法并没有得到调用,它也可能被重绘。你便会依赖调用了 invalidate() 的其他的控件以便获得正确的行为,因此每当你的 Application 发生改变时, 这种行为多要随之发生改变。也是基于次因,在你的自定义控件中你必须不断地调用 invalidate() 方法,当你的数据或者是状态会影响 View 的绘制代码时。注意: Android 的 View 当它们的属性发生改变时会自动的调用 Invalidate() 。比如, 你改变一个 Textview 的背景或者是它的文本。 2.2 基于硬件加速模型 Android 系统仍然通过 invalidate() 和 draw() 去请求屏幕更新和重新渲染,但是实际处理画的方式是不同的。不是立即执行画的命令, Android 而会将所有画的命令记录在一个显示列表里面, 这个显示列表包含了输出的 View 层级的绘制代码。还有一个优化就是 Androi d 在显示列表中只会记录和更新显示层级中通过调用 invalidate() 函数被标记为“脏”的 view 。没有被请求刷新的 view 可以通过重新请求先前的显示列表以便重画。新的绘制模型包括有三个步骤: 1. 禁用整个 View 层级。 2. 记录和更新显示列表。 3. 绘制显示列表。使用这个模型你不能依赖一个 Vie w 和脏区域有交集就会执行 draw() 方法。要确保 Android 系统记录了一个 View 的显示列表,你必须调用 invalidate() 方法, 如果忘记了调用刷新, 会使 View 即便是发生了改变后也会看起来相同,这是一个比较容易发现 bug 的方式。使用显示列表的方式对动画的表现也是很有好处的, 因为设置指定的属性值, 比如透明度或者旋转, 就不需要请求刷新目标 View( 这将自动执行)。这项优化也应用于有显示列表的 Views( 启用了硬件加速的 View) ,例如,现在有一个 LinearLayout 包含了一个 ListView 和 Button , listview 在 button 的上面。这时候 LinearLayout 的显示列表如下所示: ◆ DrawDi
1
内容来自淘豆网转载请标明出处.