`
king_tt
  • 浏览: 2260310 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Android中使用硬件加速的技巧

 
阅读更多

http://www.uzzf.com/news/2060.html

从Android 3.0开始,Android 2D的绘制流程就设计为能够更好地支持硬件加速。使用GPU的View在Canvas上进行画的操作时都会使用硬件加速。在最新的Android版本里,图形硬件加速及绘制技巧得到了更好的提升.

  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进行加速。

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

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

  1.1.4 View级别

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

  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.0View的层

  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旋转。

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

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

  View.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator animator= ObjectAnimator.ofFloat(view, "rotationY", 180); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setLayerType(View.LAYER_TYPE_NONE, null); } }); animator.start();

  4Android 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。

分享到:
评论

相关推荐

    Android开发模拟器加速

    总结起来,Android开发模拟器加速涉及多个方面,包括硬件加速技术、模拟器配置优化、使用先进的AVD管理工具、选择合适的系统镜像以及利用第三方模拟器。理解并掌握这些技巧,开发者可以大大提高模拟器的运行效率,...

    Android绘图机制与处理技巧(一)——Android绘图技巧

    - 使用硬件加速:硬件加速可以提高绘图性能,但不是所有操作都支持,需要谨慎使用。 - 使用` PorterDuff.Mode`混合模式:可以实现复杂的效果,但可能对性能有影响。 - 缓存位图:对于重复绘制的复杂图形,可以先...

    Android绘图技巧Demo

    6. **性能优化**:高效地使用Canvas,避免不必要的重绘,合理使用硬件加速,以及避免在onDraw()中执行耗时操作,都是提高应用性能的关键。 7. **绘图缓存**:对于复杂或者频繁更新的视图,使用Bitmap缓存可以显著...

    android中文帮助文档

    文档会讲解如何利用Sensor API访问设备传感器,获取位置、运动数据,以及如何进行硬件加速等优化。 六、应用发布与市场策略 文档还将涵盖应用的发布流程,包括签名、打包、测试和发布到Google Play或其他第三方应用...

    Android 模拟器加速

    "Intel HAXM (Hardware Accelerated Execution Manager)"是Intel提供的一款硬件加速器,专为提升Android模拟器的性能而设计。本文将详细介绍Intel HAXM的工作原理、安装过程以及优化技巧,帮助开发者提高开发效率。 ...

    Android开发资料详细和技巧

    另外,了解如何使用RenderScript、硬件加速等技术也是必要的。 3. **UI设计**:Android支持多种屏幕尺寸和分辨率,因此需要创建可适应不同设备的布局。使用相对布局(RelativeLayout)、约束布局(ConstraintLayout...

    android中使用gif动画

    3. 使用硬件加速:确保视图开启了硬件加速,以提升动画性能。 五、总结 在Android中使用GIF动画,可以通过第三方库轻松实现,如Glide。对于更复杂的场景,可以自定义`GIFView`进行解码和播放。同时,注意性能优化以...

    分享10种可提升Android应用运行效果的技巧

    同时,利用硬件加速等特性,可以进一步优化图形渲染效果。 #### 技巧4:启用StrictMode检测 StrictMode API能够帮助开发者检测应用中潜在的问题,如内存泄露或长时间的阻塞操作。它是自Android 2.3版本引入的,...

    Android绘图机制与处理技巧(下)

    避免不必要的重绘,使用硬件加速,正确管理内存,以及使用适当的缓存策略,都是提升绘图效率的关键。例如,可以使用`BitmapShader`复用位图,减少内存占用;或者利用` NinePatch`资源,提高位图拉伸时的性能。 6. ...

    android webview加速和透明设置例子

    1. **启用硬件加速**:在应用的AndroidManifest.xml中,为相应的Activity添加`android:hardwareAccelerated="true"`属性,这将开启硬件加速,提高WebView性能。 2. **禁用JavaScript缓存**:在某些情况下,禁用缓存...

    Android动画机制与使用技巧(四)——Android动画特效

    因此,合理地使用硬件加速、减少不必要的动画计算以及适时使用postInvalidate()方法更新UI,都能提高动画的性能。 此外,Android还提供了动画监听器(AnimatorListenerAdapter),可以监听动画的开始、结束、取消等...

    Android SDK Manager和AVD Manager使用.docx

    通过以上内容,我们不仅了解了Android SDK Manager和AVD Manager的基本使用方法,还学习了如何优化模拟器性能、真机调试技巧以及如何利用CPU虚拟化技术来提升模拟器的速度。这些都是Android开发中不可或缺的关键技能...

    Android C++高级编程:使用NDK(完整版带书签).pdf

    最后,本书可能包含了一些高级话题,比如异步编程模型(如使用libuv)、多进程通信、硬件加速以及使用NDK进行安全编程的策略。 总的来说,《Android C++高级编程:使用NDK》是Android开发者深入学习C++和NDK的宝贵...

    Android SDK 中文开发文档.pdf

    3. **图形库**:Android包含2D和3D图形库,基于OpenGL ES 1.0,提供硬件加速选项,支持丰富的视觉效果和游戏开发。 4. **SQLite数据库**:SQLite作为一个轻量级的关系型数据库引擎,为应用提供数据存储功能。 5. *...

    Android-使用Html来渲染Android界面的动态化界面方案

    可以开启硬件加速,使用`setWebChromeClient()`和`setWebViewClient()`来优化加载和渲染过程。另外,`WebView缓存策略`也可以调整,以减少网络请求。 6. **安全考虑**:由于JavaScript可以调用Android的接口,存在...

    android开发技巧与性能优化

    4. **合理使用动画**:过度使用复杂的动画效果会占用大量CPU资源,应尽量采用硬件加速方式实现动画。 5. **性能监控**:利用Android Studio自带的Profiler工具对应用进行性能监控,及时发现并解决问题。 #### 五、...

    Android 帧动画优化实现可减少内存使用

    6. **利用硬件加速**:在Android 3.0及以上版本,开启硬件加速可以提高动画性能。在Activity的`onCreate()`方法中添加`getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager....

    android ffmpeg使用

    为了提高视频处理的效率和质量,你需要关注FFmpeg的优化技巧,比如多线程解码、硬件加速支持等。此外,由于Android系统的碎片化,要确保你的应用能在各种设备上运行良好,需要对不同Android版本和硬件平台进行适配...

Global site tag (gtag.js) - Google Analytics