Android的UI调优
对于一个App的UI而言,在流畅性上的改进目标其实就是降低屏幕绘制的延迟,创建流畅和稳定的帧率以避免卡顿。
在理想情况下,全部的测量、布局和绘制的时间最好在16ms以内,这样才能保证屏幕运行的顺畅性。而如何对屏幕渲染和UI性能进行评估和分析呢,在Android SDK中集成了一些工具用来策略APP的渲染性能问题。
一、视图的层级分析:
对于每一个视图而言,都需要经过三个步骤:测量、布局和渲染。而App如何绘制视图,它需要从顶部节点开始测量,沿着布局树逐个渲染,视图树的层级越多,嵌套测量的次数越多,测量的时间也会越长。而一旦测量完毕就会进行布局,每个视图都会对自己的子视图进行布局,子视图布局完毕后回到父视图,然后再到根视图,布局完成后,每个视图都会被绘制在屏幕上。
显然,App的视图越多,层级越深就需要越长的时间测量、布局和绘制,为了减少这些时间,需要尽可能保持视图层级的扁平化并删除所有没有必要渲染的视图。
虽然在XML布局文件中可以查看布局的节点视图,单很难找到多余的视图,为了找到这些多余的视图,可以利用Android Studio中的Hierarchy Viewer工具来分析Android App中的视图。
Hierarchy Viewer(层次结构查看器)能够便捷地以可视化方式查看各种视图嵌套关系,可用于研究XML视图结构。(需要一个运行Android App的设备)
利用这个工具可以查看我们的View的层次,从而借助它修改我们的布局。
一般的建议:
使用抽象布局标签(include, viewstub, merge)主要是为了优化布局,去除不必要的嵌套和View节点。
- 视图重用
多用于ListView和RecylerView等列表形式
- 使用include嵌套布局,实现布局的模块化设计,这里需要考虑到下面谈到的merge标签的使用。
- <merge>标签
在使用了include后可能导致布局嵌套过多,多余不必要的layout节点,从而导致解析变慢,不必要的节点和嵌套可通过hierarchy viewer或设置->开发者选项->显示布局边界查看。merge标签在UI的结构优化中起着非常重要的作用,它可以删减多余的层级,优化UI。
merge多用于替换FrameLayout或者当一个布局包含另一个时,merge标签消除视图层次结构中多余的视图组。
merge标签可用于两种典型情况:
a. 布局顶结点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity内容视图的parent
view就是个FrameLayout,所以可以用merge消除只剩一个。
b. 某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自动被忽略,而将其子节点全部合并到主布局中。
- <ViewStub>
viewstub标签同include标签一样可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。
viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。
比如说,假设network_error.xml为只有在网络错误时才需要显示的布局,默认不会被解析。
当我们要使用的时候,有两种方法可以使用,效果是一样的:
((ViewStub)
findViewById(R.id.layout_error)).setVisibility(View.VISIBLE);
// 或者
View
importPanel = ((ViewStub) findViewById(R.id.layout_error)).inflate();
二、资源缩减
第一点提到的是将App的视图结构变扁平,减少视图的数量后,其实我们还可以尝试减少每个视图里使用的资源数量。(如加载时引用一个资源,在运行时进行着色)
三.屏幕的过度绘制
屏幕的过度绘制这个概念有点类似于PhotoShop中的图层的概念,上面的图层会覆盖住下面的图层,而使得下面的图层不可见。当Android系统绘制屏幕时,首先绘制父视图而后是子视图,子视图位于其父视图上。
重绘屏幕的行为被称为过度绘制,多次的屏幕绘制会增加延迟,并且可以导致布局卡顿。
既然过度绘制的影响那么大,我们应该怎么检测呢?
Android提供了一些很好的工具来检测过度绘制,而一般采用的方式是在Debug GPU Overdraw菜单中选择“Show Overdraw area”,(在本人手机中为开发者选项中的调试GPU过度绘制),选择之后会在App的不同区域覆盖不同的颜色来表示过度绘制的次数。比较屏幕上的这些不同颜色,可以快速定位问题。
白色:没有过度绘制
蓝色:1次过度绘制(屏幕绘制了2次)
绿色:2次过度绘制
浅红色:3次过度绘制
深红色:4次或更多次过度绘制
而另外一种查看方法是借助于前面提到的Hierarchy Viewer工具,将view hierarchy保存为Photoshop文档,打开这些视图后可以看到不同层次的过度绘制情况。
四、分析卡顿(策略GPU的渲染能力)
在优化视图的层次结构和过度绘制后,App还存在丢帧或者不流畅的情况,为了获得获得更加全面的卡顿检测信息,Android系统中有一个Profile GPU Rendering的开发者选项,它能够检测出每一帧在屏幕上用了多久,策略数据可以保存到日志文件中,或者在设备上实时显示。一般而言,在屏幕上直接展示GPU的渲染数据能够更加直观地看到。
在本人的手机中,在开发者选项中找到【GPU呈现模式分析】,选择【在屏幕上显示为条形图】,然后打开一个手机QQ,就发现如下图所示情况
需要关注的是底部的那一条水平绿线,它表示设备渲染一帧要16ms,每一帧就是一个水平条,如果有很多帧超过了这条绿线就说明设备出现了卡顿情况。
五、让它看起来更快
前面讲到了如果通过测试发现问题优化布局使得UI绘制更加流畅,其实还有一个方法使得UI绘制更快:让它看起来更快。
- 进度条
- 动画
- 即时更新:指用户更新了一个页面后,页面上的数据就会立刻发生变化,即使数据还没有达到服务器(这里需要确定这些数据最终一定可以更新到服务器)(离线上传,离线发送网络请求)
或者是另外一种思路,在用户添加有关图片帖子的文字时提前上传图片到服务器。
Android的UI调优的更多相关文章
- Android界面性能调优手册
界面是 Android 应用中直接影响用户体验最关键的部分.如果代码实现得不好,界面容易发生卡顿且导致应用占用大量内存. 我司这类做 ROM 的公司更不一样,预装的应用一定要非常流畅,这样给客户或用户 ...
- android性能测试与调优:使用 DDMS 查看内存分配情况
1. 启用自己的APK后 2. 点击左边更新heap 3. 点击右边的heap中的垃圾回收cause GC,等待数秒出现回收内存与数据情况(由于内存回收了APK运行出现异常crash) 4. 点击一个 ...
- Android系统性能调优工具介绍
http://blog.csdn.net/innost/article/details/9008691 经作者授权,发表Tieto某青年牛的一篇<程序员>大作. Android系统性能调优 ...
- 【Java/Android性能优3】Android性能调优工具TraceView使用介绍
本文转自:http://blog.csdn.net/innost/article/details/9008691 在软件开发过程中,想必很多读者都遇到过系统性能问题.而解决系统性能问题的几个主要步骤是 ...
- 【Java/Android性能优2】Android性能调优工具TraceView介绍
本文参考:http://www.trinea.cn/android/android-traceview/ Android自带的TraceView堪比java的性能调优工具visualvm线程视图,可以 ...
- 转: 腾讯Bugly干货分享:Android应用性能评测调优
转:http://www.kuqin.com/shuoit/20150618/346693.html?utm_source=www.race604.com 前言 在智能手机App竞争越来越激烈的今天, ...
- Android性能调优篇之探索垃圾回收机制
开篇废话 如果我们想要进行内存优化的工作,还是需要了解一下,但这一块的知识属于纯理论的,有可能看起来会有点枯燥,我尽量把这一篇的内容按照一定的逻辑来走一遍.首先,我们为什么要学习垃圾回收的机制,我大概 ...
- 【Java/Android性能优化1】Android性能调优
本文参考:http://www.trinea.cn/android/android-performance-demo/ 本文主要分享自己在appstore项目中的性能调优点,包括同步改异步.缓存.La ...
- Android性能调优
本文主要分享自己在appstore项目中的性能调优点,包括同步改异步.缓存.Layout优化.数据库优化.算法优化.延迟执行等.一.性能瓶颈点整个页面主要由6个Page的ViewPager,每个Pag ...
随机推荐
- 基于jqUI的日期选择(‘yy-mm-dd’)
今天看某公司的网页,其中有个筛选条件是选择一个时间区间,从而选择出符合条件的项.什么也不说了,先看图左边的输入框,点击具体的日期,这里我选择的是2017-3-9,然后右边的输入框就只能选择这个日期以后 ...
- 关于获取URL中传值的解决方法
在我们页面的URL中包含着很多信息,包括域名,协议等等这里就不一一介绍了),对于我们开发者而言,使用比较多的就是页面之间的传值.为什么要页面传值呢?很简单,当你在浏览一个商品页面的时候你要看到一个商品 ...
- jquery实现网页倒计时
在毕设作品考试模块要做个倒计时,当时间到时自动结束答题.于是在jQuery插件社区找到一个简洁明了的倒计时.先上效果图. 感谢作者hacker(这是黑客的意思么),贴上地址:http://www.jq ...
- 使用HTMLParser爬取标签内容
以此网站为例 import urllib.request from html.parser import HTMLParser from html.entities import name2codep ...
- 初次使用git配置以及git如何使用ssh密钥(将ssh密钥添加到github)
初次安装git配置用户名和邮箱 初次安装git需要配置用户名和邮箱,否则git会提示:please tell me who you are. 你需要运行命令来配置你的用户名和邮箱: $ git con ...
- hdu4597 Play Game 区间DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597 全国邀请赛通化赛区第8题--题目重现 思路: 区间DP的思想,想法是队友想出来的,感觉很秒,自己 ...
- Linux环境g++编译TinyXML动态库
除了CMarkup,tinyxml也是C/C++下解析XML很好的工具.在linux下用g++编译tinyxml的步骤如下(tinyxml版本2.6.2): 进入tinyxml解压目录,用文本编辑器打 ...
- 关于Java解压文件的一些坑及经验分享(MALFORMED异常)
文章也已经同步到我的csdn博客: http://blog.csdn.net/u012881584/article/details/72615481 关于Java解压文件的一些坑及经验分享 就在本周, ...
- 连续分段累计器FPGA实现的探讨
- 日志组件二:log4j2
一.背景 随着业务服务(Server App)逐渐增加,我们的业务系统中的日志输出面临的问题越来越多,高并发下对磁盘io这块消耗的越来越大,因此,急需要一个高性能且最好能够支持异步输出日志的日志框架, ...