自定义view笔记-之关于硬件加速

前言

    我们平时在开发Android的时候,经常会接触到硬件加速这个词,因为我们一般都是在应用层做开发,几乎不怎么接触硬件,其实操作系统已经把底层硬件封装的很完善了,我们并不需要去写C语言就能开启硬件加速。开启硬件加速其实非常简单

  1. 从Android 3.0(API级别11)开始,Android 2D渲染管道支持硬件加速,这意味着在View画布上执行的所有绘图操作都使用GPU。由于启用硬件加速所需的资源增加,您的应用程序将消耗更多的RAM。

  2. 如果您的目标API级别>=14,则默认情况下启用硬件加速,但也可以显式启用。如果您的应用程序仅使用标准视图和Drawable,则将其全局打开不应导致任何不利的绘图效果。但是,由于所有2D绘图操作都不支持硬件加速,因此将其打开可能会影响某些自定义视图或绘图调用。问题通常表现为不可见的元素,例外或错误渲染的像素。为了解决这个问题,Android允许在多个级别启用或禁用硬件加速。请参阅控制硬件加速。

控制硬件加速有四个级别:

  1. Application
  2. Activity
  3. Window
  4. View

Application开启硬件加速方式:

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

Activity开启硬件加速方式

<activity android:hardwareAccelerated="false" />

Window开启硬件加速方式

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

View关闭硬件加速方式

可以关闭View级别的硬件加速,但是不能在View级别开启硬件加速因为它依赖其它的设置

mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

获取是否支持硬件加速方法

 //returns true if the View is attached to a hardware accelerated window
View.isHardwareAccelerated()
// returns true if the Canvas is hardware accelerated
Canvas.isHardwareAccelerated()

软件绘制模型

    当应用中需要更新某部分UI时,将会去调用已经内容已经更改的View的invalidate(),这个通知View刷新的消息会传遍整个View的树层(android中View的视图是树形结构)来计算需要从新绘制的区域,这个区域一般称为脏区。这种模型有两种缺点

  1. 这种模型将会执行很多代码,比如某个TextView内容改变了,需要调用TextView的invalide()方法来刷新TextView,虽然我们只需要刷新TextView,但是实际上不仅仅刷新了TextView,还刷新了TextView的父控件,同理,也会刷新父控件的父控件。刷新以为着要重新执行onDraw()方法,会执行很多代码。
  2. 第二个缺点是可能会隐藏bug,因为系统会从新绘制与脏区域交叉的区域,即使你没有调用invalidate()方法,这种情况下,你依赖于另外的view刷新触发invalidate来刷新自己,但是应用程序在修改,这种情况可能会发生改变,所以因该在无论什么时候,修改了影响视图和数据的代码,我们因该在我们自定义的View中主动调用invalidate()。

硬件加速绘图模型

    Android系统仍然使用invalidate()和draw()来请求屏幕更新和渲染视图,但是以不同的方式处理实际的图形。 Android系统不是立即执行绘图命令,而是将它们记录在包含视图层次结构的绘图代码输出的显示列表中。另一个优化是Android系统只需要记录和更新由invalidate()调用标记为脏的视图的显示列表。没有失效的视图可以通过重新发布之前记录的显示列表重新绘制。新的绘图模型包含三个阶段:

  1. 使层次结构无效
  2. 记录和更新显示列表
  3. 绘制显示列表

    在硬件加速模型中,就不能依赖与脏区域相交的视图来执行draw()方法。为了确保Android系统记录视图的显示列表,您必须调用invalidate()。忘记这样做会导致视图看起来是相同的,即使它已被改变。
使用显示列表也有利于动画性能,因为设置特定属性(如alpha或旋转)不需要使目标视图无效(自动完成)。此优化还适用于具有显示列表的视图(应用程序硬件加速时的任何视图)。例如,假设有一个LinearLayout包含Button上方的ListView。
    LinearLayout的显示列表如下所示:
    DrawDisplayList(ListView控件)
    DrawDisplayList(按钮)
    现在假设你想改变ListView的不透明度。在ListView上调用setAlpha(0.5f)后,显示列表现在包含这个:
    SaveLayerAlpha(0.5)
    DrawDisplayList(ListView控件)
恢复
    DrawDisplayList(按钮)

ListView的复杂绘图代码没有执行。相反,系统只更新了更简单的LinearLayout的显示列表。在未启用硬件加速的应用程序中,列表及其父项的绘图代码将再次执行。

限制

    开启硬件加速,可以提高程序的绘制效率,提高内容改变时的刷新效率。但是硬件加速不是有百利而无一害的,它还是有它所限制的地方。受到GPU绘制方式的限制,Canvas有些方法在硬件加速开启的时候会失效或者无法正常工作,


image

总结

  1. 硬件加速就是使用GPU来代替CPU完成绘制的计算工作,它从工作分摊,和绘制机制优化来提升绘制速度。

  2. 如果我们在自定义View的时候,绘制操作不支持硬件加速,那么我们可以在自定义View中手动关闭硬件加速。

view.setLayerType(LAYER_TYPE_SOFTWARE, null); 

参数
     1. 参数为 LAYER_TYPE_SOFTWARE 时,使用软件来绘制 View Layer,绘制到一个 Bitmap,并顺便关闭硬件加速。
     2. 参数为 LAYER_TYPE_HARDWARE 时,使用 GPU 来绘制 View Layer,绘制到一个 OpenGL texture(如果硬件加速关闭,那么行为和 VIEW_TYPE_SOFTWARE 一致)。
    3. 参数为 LAYER_TYPE_NONE 时,关闭 View Layer。

  View Layer 可以加速无 invalidate() 时的刷新效率,但对于需要调用 invalidate() 的刷新无法加速。
  View Layer 绘制所消耗的实际时间是比不使用 View Layer 时要高的,所以要慎重使用

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容