随时随地技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)

从Android 3.0开始,Android的2D渲染管线可以更好的支持硬件加速。硬件加速使用GPU进行View上的绘制操作。

硬件加速可以在一下四个级别开启或关闭:

  • Application
  • Activity
  • Window
  • View

Application级别

往您的应用程序AndroidManifest.xml文件为application标签添加如下的属性即可为整个应用程序开启硬件加速:

<application android:hardwareAccelerated="true" ...>

Activity级别

您还可以控制每个activity是否开启硬件加速,只需在activity元素中添加android:hardwareAccelerated属性即可办到。比如下面的例子,在application级别开启硬件加速,但在某个activity上关闭硬件加速。

<application android:hardwareAccelerated="true">    <activity ... />    <activity android:hardwareAccelerated="false" /></application>

Window级别

如果您需要更小粒度的控制,可以使用如下代码开启某个window的硬件加速:

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

注:目前还不能在window级别关闭硬件加速。

View级别

您可以在运行时用以下的代码关闭单个view的硬件加速:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

注:您不能在view级别开启硬件加速

为什么需要这么多级别的控制?

很明显,硬件加速能够带来性能提升,android为什么要弄出这么多级别的控制,而不是默认就是全部硬件加速呢?原因是并非所有的2D绘图操作支持硬件加速,如果您的程序中使用了自定义视图或者绘图调用,程序可能会工作不正常。如果您的程序中只是用了标准的视图和Drawable,放心大胆的开启硬件加速吧!具体是哪些绘图操作不支持硬件加速呢?以下是已知不支持硬件加速的绘图操作:

  • Canvas

    • clipPath()
    • clipRegion()
    • drawPicture()
    • drawPosText()
    • drawTextOnPath()
    • drawVertices()
  • Paint
    • setLinearText()
    • setMaskFilter()
    • setRasterizer()

    另外还有一些绘图操作,开启和不开启硬件加速,效果不一样:

  • Canvas
    • clipRect(): XORDifference和ReverseDifference裁剪模式被忽略,3D变换将不会应用在裁剪的矩形上。
    • drawBitmapMesh():colors数组被忽略
    • drawLines():反锯齿不支持
    • setDrawFilter():可以设置,但无效果
  • Paint
    • setDither(): 忽略
    • setFilterBitmap():过滤永远开启
    • setShadowLayer():只能用在文本上
  • ComposeShader
    • ComposeShader只能包含不同类型的shader (比如一个BitmapShader和一个LinearGradient,但不能是两个BitmapShader实例)
    • ComposeShader不能包含ComposeShader

    如果应用程序受到这些影响,您可以在受影响的部分调用setLayerType(View.LAYER_TYPE_SOFTWARE, null),这样在其它地方仍然可以享受硬件加速带来的好处

Android的绘制模型

开启硬件加速后,Android框架将采用新的绘制模型。基于软件的绘制模型和基于硬件的绘制模型有和不同呢?

基于软件的绘制模型

在软件绘制模型下,视图按照如下两个步骤绘制:

1. Invalidate the hierarchy(注:hierarchy怎么翻译?)

2. Draw the hierarchy

应用程序调用invalidate()更新UI的某一部分,失效(invalidation)消息将会在整个视图层中传递,计算每个需要重绘的区域(即脏区域)。然后Android系统将会重绘所有和脏区域有交集的view。很明显,这种绘图模式存在缺点:

1. 每个绘制操作中会执行不必要的代码。比如如果应用程序调用invalidate()重绘button,而button又位于另一个view之上,即使该view没有变化,也会进行重绘。

2. 可能会掩盖一些应用程序的bug。因为android系统会重绘与脏区域有交集的view,所以view的内容可能会在没有调用invalidate()的情况下重绘。这可能会导致一个view依赖于其它view的失效才得到正确的行为。

基于硬件的绘制模型

Android系统仍然使用invalidate()和draw()来绘制view,但在处理绘制上有所不同。Android系统记录绘制命令到显示列表,而不是立即执行绘制命令。另一个优化就是Android系统只需记录和更新标记为脏(通过invalidate())的view。新的绘制模型包含三个步骤:

1. Invalidate the hierarchy

2. 记录和更新显示列表

3. 绘制显示列表

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上面去。

LAYER_TYPE_NONE
这个就比较简单了,不为这个View树建立单独的layer

PS:GLSurfaceView和WebView默认Layertype都是none。

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

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

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

补充于2012.4.21:

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

补充于2012.4.22

先说问题:
在硬件加速开启的情况下GLSurfaceView一旦被从View树上摘下来,会使整个窗口背景变黑,即使设置layer type为software也不管用。
经过两天的排查,发现了原因,我的程序是在C层由drawFrame(属于GLThread线程)来驱动进行绘画,当GLSurfaceView被摘下来时,GLSurfaceView的destroy方法被调用,我在destroy方法(属于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。这个可以参考Dev Guide

硬件加速 setlayertype相关推荐

  1. android硬件加速 setLayerType

    从Android 3.0开始,Android的2D渲染管线可以更好的支持硬件加速.硬件加速使用GPU进行View上的绘制操作. 硬件加速可以在一下四个级别开启或关闭: Application Acti ...

  2. Android中禁用硬件加速的几种方式

    禁用硬件加速度 Android提供了四中级别的禁用硬件加速度的方式: Application 对整个应用禁用硬件加速度 在AndroidManifest.xml中为application标签添加如下属 ...

  3. Android 错把setLayerType当成硬件加速

    一次硬件加速的讨论,setLayerType只能关闭硬件加速,和layer的作用!!! 硬件加速默认开启,layerType默认为none 硬件加速 在硬件加速关闭的时候,Canvas 绘制的工作方式 ...

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

    [51CTO独家特稿]从Android 3.0开始,Android 2D的绘制流程就设计为能够更好地支持硬件加速.使用GPU的View在Canvas上进行画的操作时都会使用硬件加速.在最新的Andro ...

  5. Android 系统(66)---Android硬件加速相关问题总结

    Android硬件加速相关问题总结 从Android 3.0开始就支持硬件加速,充分利用GPU的特性,使得绘制View的时候更加平滑.例如在ListView(GridView)或者WebView中使用 ...

  6. android关闭硬件动画加速器,Android中的硬件加速

    从Android 3.0开始,Android的2D渲染管线可以更好的支持硬件加速.硬件加速使用GPU进行View上的绘制操作. 硬件加速可以在一下四个级别开启或关闭: Application Acti ...

  7. 安卓禁用硬件加速_Android硬件加速

    最近项目中遇到了因为硬件加速引起的一些问题,故这里深入学习了解一下关于硬件加速的一些东西 背景 什么是硬件加速? 硬件加速是Android系统在绘制图形时采取的一种方式. 图形的绘制,本质上就是界面的 ...

  8. canvas使用硬件加速

    之前用 canvas 裁剪 绘制 bitmap, 发现bitmap显示用的缓存,没有裁剪, setLayerType(View.LAYER_TYPE_SOFTWARE,null);就可以了: Andr ...

  9. 关于android 手机硬件加速问题

    关于安卓手机的硬件加速问题 分类: Android基础  2012-04-12 14:44  740人阅读  评论(0)  收藏  举报 最近听同事讨论硬件加速问题,完全不懂.于是乎,百度了下,原来从 ...

  10. 安卓禁用硬件加速_[转]Android如何关闭硬件加速

    硬件加速 Android 3.0 (API level 11), 开始支持 所有的View 的canvas都会使用GPU,但是硬件的加速会占有一定的RAM. 在API >= 14上,默认是开启的 ...

最新文章

  1. 教你如何 构建基本的用户控件
  2. python中 使用join()方法 对各种数据类型中元的素进行合并拼接
  3. 无人驾驶图像数据集_自动驾驶数据集
  4. C语言打印字符串的所有排列组合(附完整源码)
  5. 深入理解lua的协程coroutine
  6. 算法导论-概率发生器
  7. 开发高级 Web 部件
  8. android 动态广告图片,android – 如何在动态壁纸的设置屏幕中添加一个admob广告视图?...
  9. python dict遍历性能_python 字典(dict)遍历的四种方法性能测试报告
  10. 如何做相册_我是如何对2000张照片进行批量套版的
  11. apache部署mo_python
  12. liunx 系统下面安装jdk
  13. 微信公众号开发:消息处理
  14. 【路径规划】基于matlab改进的人工势场算法机器人避障路径规划【含Matlab源码 1151期】
  15. java工程师职业价值观_什么是职业价值观?舒伯职业价值观测试
  16. [NOI2014]起床困难综合症
  17. 2005年国内最有份量的资源下载网站一览
  18. 浅谈防火墙对 FTP 的影响及故障排除
  19. 小重山 2022年4月22日
  20. 踩坑-helloJs实现google、facebook、twitter等第三方登录

热门文章

  1. 数模国赛备赛(1)元胞自动机CA 生命游戏 森林火灾 传染病模型 MATLAB版资源整理
  2. H3C模拟器如何连接SecureCRT8.7
  3. 高级语言 和 低级语言 的区别
  4. python tkinter输入框_自制tkinter输入框Inputbox类
  5. 合格的攻击性白帽黑客应该具备的基本素质(1)
  6. 利用python通过站长之家查询ip地址归属地
  7. 位偏移 java_时区和偏移类 / Zone and Offset
  8. 锋迷商城spring-vue项目流程和笔记
  9. WinKawaks详尽使用说明
  10. html的过渡属性,CSS3中的元素过渡属性transition解析