Android高级进阶之-性能优化-UI优化

为什么会有UI优化的概念?因为UI过程过于复杂,就会导致界面、动画卡顿,影响用户体验。

屏幕上的图形、文字等,都是经过CUP和GPU的计算,然后绘制到屏幕上的,所以首要任务就是了解CPU和GPU的工作流程。

CPU的任务繁重,除做逻辑运算外,还要做内存管理、显示操作,因此在实际运算的时候性能会大打折扣,在没有GPU的时代,不能显示负责的图形,其运算速度远跟不上今天复杂三维游戏的要求。这时就需要专门负责显示计算的GPU。

image.png
image.png

黄色的 Control 为控制器,用于协调控制整个 CPU 的运行,包括取出指令、控制其他模块的运行等; 绿色的 ALU ( Arithmetic Logic Unit )是算术逻辑单元,用于进行数学、逻辑运算;
橙色的 Cache 和 DRAM 分别为缓存和 RAM ,用于存储信息。

从结构图可以看出, CPU 的控制器较为复杂,而 ALU 数量较少。因此 CPU 擅长各种复杂 的逻辑运算,但不擅长数学尤其是浮点运算。

image.png

CPU负责将图形元素进行一系列初步的运算,得到图形的纹理信息,然后将纹理信息丢给GPU,GPU负责将纹理信息进行更复杂的运算,得到最终的位图,显示器直接按照位图的像素信息渲染,就完成了显示图形的整个流程。

60Hz 刷新频率由来

12 fps :由于人类眼睛的特殊生理结构,如果所看画面之帧率高于每秒约 10-12 帧的时候,就会 认为是连贯的
24 fps :有声电影的拍摄及播放帧率均为每秒 24 帧,对一般人而言已算可接受
30 fps :早期的高动态电子游戏,帧率少于每秒 30 帧的话就会显得不连贯,这是因为没有动态模 糊使流畅度降低
60 fps 在与手机交互过程中,如触摸和反馈 60 帧以下人是能感觉出来的。 60 帧以上不能察觉 变化
当帧率低于 60 fps 时感觉的画面的卡顿和迟滞现象

Android 系统每隔 16ms 发出 VSYNC 信号 (1000ms/60=16.66ms) ,触发对 UI 进行渲染, 如果每次渲染都成 功这样就能够达到流畅的画面所需要的 60fps ,为了能够实现 60fps ,这意味着计算渲染的大多数操作都必须 在 16ms 内完成。

image.png

16 毫秒的时间主要被两件事情所占用
第一件:将 UI 对象转换为一系列多边形和纹理。
第二件: CPU 传递处理数据到 GPU 。
所以很明显,我们要缩短 这两部分的时间,也就是说需要尽量减少对象转换的次数,以及GPU上传数据的次数。

如何减少这两部分的时间 以至于在 16ms 完成呢?
CPU 减少 xml 转换成对象的时间
GPU 减少重复绘制的时间

image.png

image.png

Android主题会有背景,我们可以考虑去除这个背景,减少一次不必要的渲染。


image.png

另外,我们的布局文件如果不是业务需要,尽量不指定背景。


image.png

自定义view,减少过度绘制
先看效果


优化之前
优化之后

很明显,中间区域在未优化之前,三中图片有重叠部分,明显存在过度绘制问题。
优化前的代码:

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        mDroidCards.forEachIndexed { index, droidCard ->
            if (index == mDroidCards.lastIndex) {
                drawDroidCard(canvas, droidCard)
            } else {
                drawDroidCard(canvas, droidCard, index)
            }
        }

        invalidate()
    }

    private fun drawDroidCard(canvas: Canvas?, droidCard: DroidCard, index: Int) {
//        canvas?.save()
//        canvas?.clipRect(droidCard.x.toFloat(), 0f, mDroidCards[index + 1].x.toFloat(), droidCard.height.toFloat())
        drawDroidCard(canvas, droidCard)
//        canvas?.restore()
    }

    private fun drawDroidCard(canvas: Canvas?, droidCard: DroidCard) {
        canvas?.drawBitmap(droidCard.bitmap, droidCard.x.toFloat(), 0f, mPaint)
    }

优化后的代码:

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        mDroidCards.forEachIndexed { index, droidCard ->
            if (index == mDroidCards.lastIndex) {
                drawDroidCard(canvas, droidCard)
            } else {
                drawDroidCard(canvas, droidCard, index)
            }
        }

        invalidate()
    }

    private fun drawDroidCard(canvas: Canvas?, droidCard: DroidCard, index: Int) {
        canvas?.save()
        canvas?.clipRect(droidCard.x.toFloat(), 0f, mDroidCards[index + 1].x.toFloat(), droidCard.height.toFloat())
        drawDroidCard(canvas, droidCard)
        canvas?.restore()
    }

    private fun drawDroidCard(canvas: Canvas?, droidCard: DroidCard) {
        canvas?.drawBitmap(droidCard.bitmap, droidCard.x.toFloat(), 0f, mPaint)
    }

结论:
通过canvas.clipRect方法,裁剪出需要绘制的区域,避免重复绘制。

使用Layout Inspector检查View hierarchy。


image.png

这里可以清晰看到View的树桩结构,我们需要减少树的层级,减少控件的渲染时间。

可以使用merge标签简化层级。

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

推荐阅读更多精彩内容

  • 界面是 Android 应用中直接影响用户体验最关键的部分。如果代码实现得不好,界面容易发生卡顿且导致应用占用...
    passiontim阅读 1,670评论 0 8
  • 界面是 Android 应用中直接影响用户体验最关键的部分。如果代码实现得不好,界面容易发生卡顿且导致应用占用大量...
    Ten_Minutes阅读 670评论 0 9
  • 注:本文是我在 Android 界面性能调优知识的系统性总结,纯属个人碎碎念。秉持开源分享的原则发布本文出来,各位...
    东经315度阅读 663评论 0 8
  • 昨夜碧天 倏生眩目的颜色 长睫挥动情云 遥遥迢迢 苦恋浮移的背影 以往河边 谁的琴如流水 淹没身后 几许 潇洒...
    龙生于海阅读 227评论 8 37
  • 偶然从朋友圈知道了这样一个APP,好奇与最初的写作之梦驱使我下载下来,许久都不曾读书写字,想要写上一大段话...
    S苏她阅读 230评论 0 0