`
263229365
  • 浏览: 473634 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android 4.0的图形硬件加速及绘制技巧

 
阅读更多

 

2011-11-16 10:35 傻蛋 51CTO.com 我要评论(1) 字号:T | T
一键收藏,随时查看,分享好友!

最新的Android 4.0有很多新特性,51CTO特约了魅族Android开发工程师、最牛网站长作为本站专栏作者,为各位网友撰写Android 4.0开发相关文章。本文我们将探讨Android 4.0的图形硬件加速及绘制技巧如何得到了更好的提升。

AD:

 

【51CTO独家特稿】从Android 3.0开始,Android 2D的绘制流程就设计为能够更好地支持硬件加速。使用GPU的View在Canvas上进行画的操作时都会使用硬件加速。在最新的Android版本里,图形硬件加速及绘制技巧得到了更好的提升,51CTO特约了最牛网站长作为本站专栏作者,为各位网友撰写Android 4.0开发相关文章。

Android 4.0

Android 4.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:hardwareAccelerated属性。下面的一个列子使整个Application启用硬件加速,但是对一个Activity禁止使用硬件加速。

1.1.3 Window级别

如果你需要更细粒度的控制,你可以通过如下代码给window进行加速。

  1. getWindow().setFlags( 
  2. WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); 

注意:现阶段你不能在Window级别对它禁用硬件加速。

1.1.4 View级别

我们可以对单独的View在运行时阶段禁用硬件加速。我们可以使用如下代码:

  1. myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

注意:现阶段不能够在View级别进行硬件加速。

1.2 判断一个View是否已经启用了硬件加速

有时候我们需要知道一个应用程序是否已经启用了硬件加速,特别是针对一些自定义控件。因为你的应用程序做了很多自定义“画”的操作,但并不是所有的过程都支持新的“画”的渲染过程。

有两种不同的方法来检查Application是否启用了硬件加速:

1.2.1 使用View.isHardwareAccelerated() 如果返回true则可以说明这个View所在的窗口已经启用了硬件加速。

1.2.2 Canvas.isHardwareAccelerated() 如果返回true则说明这个Canvas已经启用了硬件加速。

如果你必须要在你的绘画代码中进行是否已经加速的检查,如果可能的话请使用Canvas.isHardwareAccelerated()来代替View.isHardwareAccelerated()。当一个View是存在于一个已经加速的Windows上时,任然可以使用没有硬件加速的Canvas进行绘画,这场发生在,比如,当我们把一个View画到Bitmap上然后用作缓存。

 

 

2.Android 4.0的绘制模型

当开启了硬件加速,Android框架将会使用一种新的绘制模型,这种模型将会使用显示列表把你的应用显示到屏幕上。要完全理解显示列表和他们如何影响你的应用程序,理解Android 4.0如何在非硬件加速的情况下如何绘制Views是很有必要的,下面将分别介绍软件加速和硬件加速。

2.1基于软件的绘制模型

在基于软件绘制模型中,View的绘制遵循以下两步:1.使整个控件层级无效。2.对层级进行绘制。

当一个应用程序需要更新它UI的一部分时,它将会调用内容发生改变的View的invalidate()方法(或者invalidate的变体)。Invalidate的消息按照View的层级关系向上传递用以计算需要重画的部分(即脏区域)。然后Android系统会对和脏区域有交集的所有View进行绘制,不幸的是这种模型中有两个缺点:

2.1.1 在这种模型中当在不同的层进行画的时候,会额外执行很多代码。例如一个Button是位于另外一个View之上,当对Button调用 Invalidate()时,Android就会对这个View进行重绘,即便这个View没有发生任何变化。

2.1.2 第二个问题是这种绘制模型会隐藏你Application中的Bug。因为Android系统会对和脏区域有交集的View进行重绘,在这种情况下如果一个view的内容发生了改变,即便这个View的Invalidate()的方法并没有得到调用,它也可能被重绘。你便会依赖调用了invalidate()的其他的控件以便获得正确的行为,因此每当你的Application发生改变时,这种行为多要随之发生改变。也是基于次因,在你的自定义控件中你必须不断地调用invalidate()方法,当你的数据或者是状态会影响View的绘制代码时。

注意:Android的View当它们的属性发生改变时会自动的调用Invalidate()。比如,你改变一个 Textview的背景或者是它的文本。

2.2 基于硬件加速模型

Android 系统仍然通过invalidate()和draw()去请求屏幕更新和重新渲染,但是实际处理画的方式是不同的。不是立即执行画的命令,Android而会将所有画的命令记录在一个显示列表里面,这个显示列表包含了输出的View层级的绘制代码。还有一个优化就是Android在显示列表中只会记录和更新显示层级中通过调用invalidate()函数被标记为“脏”的view。没有被请求刷新的view可以通过重新请求先前的显示列表以便重画。新的绘制模型包括有三个步骤:1.禁用整个View层级。2.记录和更新显示列表。3.绘制显示列表。

使用这个模型你不能依赖一个View和脏区域有交集就会执行draw()方法。要确保Android系统记录了一个View的显示列表,你必须调用invalidate()方法,如果忘记了调用刷新,会使View即便是发生了改变后也会看起来相同,这是一个比较容易发现bug的方式。

使用显示列表的方式对动画的表现也是很有好处的,因为设置指定的属性值,比如透明度或者旋转,就不需要请求刷新目标View(这将自动执行)。这项优化也应用于有显示列表的Views(启用了硬件加速的View),例如,现在有一个LinearLayout包含了一个ListView和Button,listview在button的上面。这时候LinearLayout的显示列表如下所示:

◆DrawDisplayList(ListView) ;

◆DrawDisplayList(Button) ;

假设你现在你想更新这个Listview的不透明度,在设置Listview的 setAlpha(0.5f) 属性之后,LinearLayout的显示列表应该包含如下:

◆ SaveLayerAlpha(0.5)

◆ DrawDisplayList(ListView)

◆ Restore

◆ DrawDisplayList(Button)

这时候绘制Listview的复杂过程就会省略了,取而代之的是简单的更新了LinearLayout的显示列表。如果一个应用程序并没有启用硬件加速,Listview和它的父view的画的代码都会重新执行。

 

 

3.Android 4.0 View的层

3.1层的分类

所有的Android版本都有能力对离屏缓冲进行渲染,或者是使用View的绘制缓冲,或者是使用Canvas.saveLayer()函数。离屏缓冲或者Layer能够有很多种应用,例如能使处理复杂view的动画效果或者应用一些合成效果都有更好地表现。例如你可以通过Canvas.saveLayer()的方式来对View做一个渐入渐出效果同时把它渲染到Layer中,然后再加上不透明效果合成后显示到屏幕上。

由Android 3.0开始你就能够通过View.setLayerType()方法对何时以及如何使用层有了更多的控制,这个API具有两个参数一个是你想使用的层类型,另外一个是可选参数Paint表明了Layer是如何被叠加的。你可以把Paint参数应用到颜色过滤上,特别是混合模式或者是对一个layer进行不透明效果。一个View可以使用如下的三种layer类型之一:

◆ LAYER_TYPE_NONE: 这个View将被按普通的方式进行渲染,但是不会返回一个离屏的缓冲,这个是默认的行为。

◆ LAYER_TYPE_HARDWARE:如果这个应用被硬件加速的话,这个View将会在硬件中渲染为硬件纹理,如果应用程序并没有被硬件加速,则其效果和LAYER_TYPE_SOFTWARE是相同的。

◆ LAYER_TYPE_SOFTWARE: 此View 通过软件渲染为一个bitmap。

3.2 层的使用

使用层的类型取决于你的目的:

3.2.1 性能:使用硬件层来渲染一个View成为硬件纹理。一旦一个View被渲染为一个层,它的绘制代码将不会得到执行,直到你调用了invalidate()函数。对于一些动画,比如透明动画可以直接应用到一个层上,这是GPU最有效率的使用方式。

3.2.2 显示效果:使用硬件或者软件层和Paint来对一个View进行特殊的视觉处理,例如你可以对一个View通过使用ColorMatrixColorFilter来实现黑白效果。

3.2.3 兼容性:使用软件层类型会强制使一个view在软件中被渲染。如果一个view是硬件加速的话(比如你设置整个应用程序是硬件加速的话),同时有渲染的问题,这是一种很简单的方式来限制硬件绘制流程。

3.3 View的层和动画的关系

当你的应用程序已经使用了硬件加速的话,硬件层能够带来更为快速和更为平滑的动画效果。当对一个复杂的View进行动画操作时,因为要进行很多的画操作,所以并不可能总是能达到60帧每秒。在这种情况下可以通过硬件层来渲染为硬件纹理来提高性能。硬件纹理操作可以用作对一个view进行动画操作,当进行动画的时候可以减少对View自身频繁的重绘。除非你改变这个view的属性(调用invalidate()方法)或者你手动的调用invalidate()。如果在你的应用中运行一个动画,但是并没有得到你想要的平滑效果,可以考虑为你要动画的view开启硬件层。

当一个View通过硬件层返回时,当所有的层叠加后最终的画面显示在屏幕时,View一些属性会被同时被处理。设置这些属性是十分有效率的,因为他们不需要View去invalidate和重绘。如下的属性将影响层的叠加,设置这些属性将会使View自动请求刷新,而且不需要对View进行重绘。

◆alpha: 改变层的透明度。

◆x, y, translationX, translationY: 改变层的位置

◆scaleX, scaleY: 改变层的大小

◆rotation, rotationX, rotationY:在3D空间内改变层的方向

◆pivotX, pivotY: 指定它进行变形的原点位置

这些属性是通过ObjectAnimator对象对一个view进行动画操作时所使用的,如果你想访问这些属性,直接调用这些属性的setter或者getter方法,例如想改变View的alpha则直接调用setAlpha()。如下的代码片段显示了一个View通过Y轴进行3D旋转。

  1. view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
  2. ObjectAnimator.ofFloat(view, "rotationY", 180).start(); 

因为硬件层会消耗视频的内存,强烈的推荐你在作动画的时候启用他们,当动画完成了之后禁用他们,你可以通过动画监听来完成这些。代码如下:

  1. View.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
  2. ObjectAnimator animatorObjectAnimator.ofFloat(view, "rotationY", 180); 
  3. animator.addListener(new AnimatorListenerAdapter() { 
  4. @Override 
  5. public void onAnimationEnd(Animator animation) { 
  6. view.setLayerType(View.LAYER_TYPE_NONE, null); 
  7. }); 
  8. animator.start(); 

 

Android 4.0提示和技巧

切换到硬件加速2D图形可以立即增强表现,但是你还是需要通过如下的建议来设计你的应用程序来更有效率的使用GPU。

4.1 减少你程序中使用View的数量

你系统中画的view的数量越多,你的程序就会越慢,在软件绘制的流程也是一样的,减少view的数量是优化你UI的一个最简单的方法。

4.2 避免过多绘制

不要过多的叠加层,当一个View被其他view完全遮挡住了的话,最好把被遮挡的view移除掉。如果你需要绘制不同的层做一个叠加效果的话,考虑把这些层合并为一个层。就现在的硬件来看,有一个好的经验就是动画的每帧不要绘制多余屏幕像素2.5倍的像素数量(bimap中的透明像素也计算在内)。

4.3 不要在绘制的方法中创建绘制对象

一个常见的错误就是当绘制方法被调用的时候,每次都要创建一个新的Paint或者Path。这将迫使垃圾回收器过于频繁的运行,这将对缓冲和硬件的绘制造成影响。

4.4 不要过于频繁的修改形状

以复杂的shapes,path和旋转为例,这些绘制都会用到纹理的遮罩。每当你创建或者修改一个path,硬件渲染过程都会创建一个新的遮罩,这耗费的代价是相当大的。

4.5 不要过于频繁的修改bitmap

每当修改一次bitmap的内容,当你下次再绘制它的时候都会以GPU的纹理形式上传一次。

4.6 要小心使用alpha通道

当你使用setAlpha ,AlphaAnimation或者ObjectAnimator设置一个View的透明效果时。它将需要2倍离屏的渲染缓冲填充率,当应用一个alpha到一个大的View上的时候,考虑设置view 层的类型为LAYER_TYPE_HARDWARE。

本文作者的微博为http://weibo.com/zuiniuwang 欢迎大家与他联系。

【51CTO.com独家特稿,非经授权谢绝转载,合作媒体转载请注明原文作者及出处!】

 

 

<!--EndFragment--> <!--EndFragment-->

 

<!--EndFragment-->

 

<!--EndFragment-->

 

分享到:
评论

相关推荐

    android4.0测试代码

    3. **硬件加速**:ICS默认启用了硬件加速,这对性能提升有显著作用,但也可能引发一些图形绘制问题。测试时需检查应用在硬件加速下的运行情况,特别是自定义视图和动画。 4. **Action Bar**:Action Bar作为ICS中的...

    仿android4.0 switch控件

    这篇博客“仿android4.0 switch控件”可能探讨了如何在更早或自定义版本的Android系统上实现与Android 4.0相似的Switch效果。 首先,我们来了解下原生Android 4.0 Switch控件的特点: 1. **设计风格**:Android 4.0...

    android SDK 4.0 & api15 源码

    3. **硬件加速**:Android 4.0开始广泛采用硬件加速,提高了图形性能,减少了CPU负载。源码中的View系统和OpenGL ES库的集成展示了如何利用硬件加速进行UI渲染。 4. **Android 4.0的兼容性**:此版本的目标是兼容...

    android4.0做的登录

    9. **UI性能优化**:Android 4.0对UI渲染进行了优化,支持硬件加速,提升了界面滑动的流畅性。在设计登录界面时,要注意避免过度绘制,以确保良好的性能。 10. **调试工具**:Android Studio在4.0时代已经有了很大...

    android 4.0 samples

    Android 4.0(ICS)作为Android系统的一个重要里程碑,引入了许多新特性,如Holo主题、多任务处理、以及更强大的硬件加速。通过分析这些示例,开发者可以快速了解如何在自己的应用中利用这些新特性。 二、关键示例...

    external目录skia、libjpeg-turbo库,android4.0至8.0不同版本

    在Android中,Skia主要负责图形渲染工作,比如UI元素的绘制、硬件加速的2D图形以及图像滤镜等。通过分析不同版本的Skia源码,我们可以了解到Android在图形性能优化上的改进和新功能的引入。 在`external7.rar`到`...

    安卓九宫格解锁源码,android4.0风格

    这个源码是基于Android 4.0(Ice Cream Sandwich)风格的九宫格解锁机制实现,与Android 4.1(Jelly Bean)的解锁方式兼容。下面我们将深入探讨这种解锁方式的关键技术和实现细节。 1. **解锁界面设计**:九宫格...

    Android eclipse画板绘制不同颜色图形,有助于初学Android的童鞋了解Android绘图机制

    本文将深入探讨如何使用Eclipse的画板(Canvas)功能来绘制不同颜色的图形,这对于初学者理解Android的绘图机制至关重要。 首先,让我们了解Android中的Canvas。Canvas是Android图形系统的核心组件之一,它允许...

    安卓自定义控件相关-Android4.0风格中文滚动输入.zip

    "安卓自定义控件相关-Android4.0风格中文滚动输入.zip"这个压缩包包含了一个旨在实现Android 4.0(ICS,Ice Cream Sandwich)风格的中文滚动输入控件。这种控件可能用于日期选择、地区选择或任何需要用户滚动选取...

    Android 4.0下指南针开发源码

    总之,开发Android指南针应用不仅涉及到硬件传感器的使用,还涵盖了Android系统API的深入理解、图形绘制以及设备兼容性处理等多个方面。通过实践,开发者不仅可以提升技术能力,还能为用户提供实用且有趣的工具。

    Android应用源码之Android 4.0下指南针开发源码,可在Nexus 4上完美运行-IT计算机-毕业设计.zip

    - Android 4.0(API级别14)是开发的目标平台,这意味着应用至少支持Android 4.0及以上版本的设备。 - Nexus 4是一款运行Android系统的智能手机,表明源码经过了实际设备的测试和验证。 2. **AndroidManifest.xml...

    Android应用源码之Android 4.0下指南针开发源码,可在Nexus 4上完美运行.zip

    - **图形绘制**:如何在SurfaceView上绘制自定义的指南针指针。 - **传感器数据转换**:理解如何将传感器数据转换为实际的方位信息。 - **UI更新与动画**:学习如何实时更新UI以及实现平滑的动画效果。 - **Android...

    详解Android开发中硬件加速支持的使用方法

    在Android开发中,硬件加速是一项重要的优化技术,它利用设备的GPU来处理图形绘制任务,以提高应用的性能和流畅性。自Android 3.0(API Level 11)开始,系统开始支持硬件加速,使得UI动画和复杂的视图渲染更加平滑...

    在 Android 轻松绘制 Vector 动画.zip

    5. **兼容性**:该项目兼容Android 4.0 (API级别14)及以上的版本,覆盖了广泛的目标用户群体。 6. **社区支持**:作为一个开源项目,RichPath拥有活跃的社区,开发者可以提交问题、讨论解决方案,并贡献自己的代码...

    Android2.3实现Android4.0风格EditText的方法

    - 《Android视图View技巧总结》涉及优化和定制视图的实用技巧,如自定义控件和绘制图形。 - 《Android布局layout技巧总结》则是学习如何高效地使用各种布局管理器来组织界面元素。 总之,通过逐步掌握Android各个...

    中关村黑马程序员训练营android-4.0视频下载地址

    - **内容介绍**:讲解了如何在Android应用中使用图像资源、绘制图形和文本,以及如何实现基本的2D图形操作。 #### 8. DDMS工具 - **视频链接**:http://www.400gb.com/file/64194953 - **内容介绍**:DDMS(Device ...

    理解Android硬件加速原理(小白文)

    在Android系统中,硬件加速是一种优化技术,它利用GPU(图形处理器)来处理图形绘制,以提高应用性能和用户体验。与传统的软件绘制相比,硬件加速不仅提升了绘制速度,还在构建绘制区域和渲染流程上进行了优化。 1....

    安卓Android源码——4.0下指南针开发源码,可在Nexus4上完美运行.zip

    总的来说,这个指南针开发源码是一份宝贵的教育资源,可以帮助开发者深入了解Android系统的传感器使用、图形绘制、设备适配以及性能优化等多个方面。通过分析和学习这份源码,开发者可以提升自己在Android应用开发中...

    graphic android systhem

    ### 关于Android图形系统...综上所述,这份文档为我们展示了Android图形系统从2.2到4.0版本的发展历程,以及各个版本中图形处理的关键技术和优化方法。这对于理解Android图形系统的架构和演变过程具有重要的参考价值。

Global site tag (gtag.js) - Google Analytics