Android 硬件加速简介

硬件加速的原理

将view的绘制函数转化成OpenGL中的函数来完成绘制。

软件绘制与硬件绘制的区别

  • 软件绘制
    在软件绘制模式,view是按照下面两个步骤进行绘制的:
  1. 无效化View层次结构
  2. 绘制View的层次结构

绘制的特点:
当应用需要更新它的一部分UI,它会调用view的invalidate方法,无效化消息就会通过各种途径传递到View的层次结构,然后计算屏幕中需要重绘的区域(脏区域),android系统还会对View层次结构中脏区域相交的所有view进行绘制。

不足:
1. 这个模式在每一次绘制都需要执行大量的代码,比如,如果你的应用对一个button调用invalidate,而这个button坐标在其他view的上方,那么android系统就会重绘这些view,即使他们没有发生改变,仅仅因为它们处于和button相交的区域。
2. 由于一个view的绘制可能导致另一个view重绘,因此会引起一些不被注意到的bug。

  • 硬件绘制
    新的绘制模式包含三个步骤:
  1. 无效化View的层次结构
  2. 记录和更新显示列表
  3. 绘制显示列表

android系统依然使用invalidate和draw函数来请求屏幕刷新渲染界面,但实际上绘制的时候是有区别的,不同于立即执行绘制命令,android系统会先把它们记录在display list上,这个display lists包含view的层次结构的绘制代码。其他的优化是android系统只需要记录和更新display lists,通过调用invalidate函数来标记那些脏view,那些没有被标记为invalidate的view可以简单的进行重绘通过事先记录在display list上的记录。

举个栗子:
例如,假设有一个LinearLayout在Button上面有一个ListView,那么对于LinearLayout的display list就会像这样的:
DrawDisplayList(ListView)
DrawDisplayList(Button)
假设现在你通过调用setAlpha(0.5)来修改ListView的透明度,那么display list就变成这样了:
SaveLayerAlpha(0.5)
DrawDisplayList(ListView)
Restore
DrawDisplayList(Button)

关于ListView的复杂的绘制代码并没有被执行,系统只是更新了LinearLayout的display list,如果应用没有启用硬件加速,那么listview以及它的父容器LinearLayout的绘制代码都会再次执行。

硬件加速的优势

  • 流畅性更好:切换到硬件加速,界面固然是更加流畅了,但是我们开发应用的时候要想让GPU的效率更加的高。

  • 性能更好:硬件加速的优势在于display list这个设计,使用这个的话,我们就不需要每次重绘都执行大量的代码,因为对脏区域的,基于软件的绘制模式会重绘脏区域内的所有控件,而display只会更新列表,然后绘制列表内的控件。

硬件加速的弊端

  • 消耗更多的内存:由于要把系统中OpenGL加载到内存,所以OpenGL API调用就会占用8MB,而实际上会占用更多内存,并且使用了硬件必然增加耗电量了。
  • 兼容性:硬件加速是从API 11引入,API 14之后才默认开启。对于标准的绘制操作和控件都是支持的,但是对于自定义View的时候或者一些特殊的绘制函数就需要考虑是否需要关闭硬件加速。

tips

  • 1.当你的应用是硬件加速的,硬件图层类型可以传达更快和更加顺滑的动画,当你在处理的是一个复杂的又很多绘制操作的view的时候,运行一个动画不总是60帧每秒的。可以通过使用硬件层来渲染view到一个硬件的texture中来优化这个问题,硬件texture可以用来对view进行动画,排除开始动画的时候需要重绘自己的View,view不会重新重绘除非你改变它的属性,然后调用invalidate()。
    如果你运行一个动画在你的应用上,但是得不到一个你想要的顺滑结果,考虑启用硬件加速在你的动画view上。当view从硬件图层回退的时候,它的一些属性会通过图层合成到屏幕上的方式进行处理,设置这些属性将会更加高效,因为它不需要view重绘或者无效化。
    因为硬件层消耗video存储,所以强烈建议启用它们只有在动画时长并且关闭它们当动画完成的时候,你可以完成这个通过使用动画监听器,这一个比较细节,但能够对View进行优化,毕竟手机内存这么少。
    示例代码应该是这样
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();
  • 2. 小心使用alpha属性
    当你使用setAlpha,或者AlphaAnimation,或者ObjectAnimator来改变一个View的透明度时,它渲染在离屏缓存中需要两倍填充率,当需要在在一个非常大的view上修改alpha,就要考虑设置view的layer type为LAYER_TYPE_HARDWARE。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容