《移动App性能评测与优化》笔记--APP性能测试之FPS\流畅度

1、FPS

腾讯GT为了更准备的来评测App的流畅度,寻找了一种新的评测方法来替代FPS,把这种新的方法命名为流畅度(SM)

用FPS测试APP时遇到的问题:

1)为什么有时候FPS很低,但是我们却不觉得App卡顿?

2)App停止操作之后,FPS还是一直在变化,这样的情况是否会影响FPS的准确度?

系统获取FPS的原理是这样的:手机屏幕显示的内容是通过Android系统的SurfaceFLinger类,把当前系统里所有进程需要显示的信息合成一帧,然后提交到屏幕进行显示。FPS就是1s内SurfaceFLinger提交到屏幕的帧数

根据原理,就可以解答上面的两个问题:

1)有时候FPS很低,我们却感觉不到卡顿,是因为如果你的App在1s内只有30帧的显示需求,比如画一个动画只画了0.5秒就画完了,那么FPS最高也只有30帧/秒,但这并不代表它是卡顿的。而如果屏幕根本没有绘制需求,即屏幕显示的画面是静止的,那FPS就为0。

2)App停止操作后FPS还一直变化,是因为屏幕每一帧的合成都是针对手机里的所有进程,那么即使你的App停止了绘制,手机里其他进程可能还在绘制,比如通知栏的各种消息,这会导致FPS继续变化。从这里我们也能看出,在测试的时候,其他的进程对FPS也是有影响的

通过分析发现,用FPS来衡量APP的流畅度,并不一定准确,通过研究FPS的获取原理,我们对Android的绘制显示系统有了初步的了解,然后我们再对Android的绘制显示系统进行进一步的分析,终于找到了一种全新的衡量流畅度的方式,就是我们上面说的SM。

(此处需要深入的了解Android绘制机制和原理)

流畅度优化过程:

1、通过SM对APP的流畅度进行测试评估

2、然后从最简单的App UI层入手,优化App的UI来提升流畅度。

  • GPU过度绘制+Trace for OpenGL,解决UI过度绘制的问题(过度绘制是指在屏幕一个像素上绘制多次,可以通过Tracer for OpenGL ES进行详细的观察)
  • Hierarchy Viewer,查找UI布局不合理的地方,主要进行以下几种分析:                                                                                          1、没有用的父布局。没有用的父布局是指没有背景绘制或者没有大小限制的父布局,我们把没有用的父布局通过<merge/         >标签合并来减少UI的层次。       

           2、使用线性布局LinearLayout排版导致UI层次变深。如果有这类问题,我们就使用相对布局RelativeLayout代替                               LinearLayout,减少UI的层次 

           3、不常用的UI被设置成了GONE,比如error页面,如果有这类问题,我们需要用<ViewStub />标签代替GONE提高UI性能

3、接着通过lint静态扫描发现一部分代码中存在的性能(Performance)问题,然后进行优化。

4、最后再进一步深入的分析和解决App逻辑层和IO层存在的问题--使用工具Traceview以及Systrace。

  • 找出在主线程耗时较大的函数,看看是否能够通过优化逻辑去减少API的耗时,优化的方案大概是缓存某些数据在需要的时候能够更快地加载,或者把耗时的操作移出主线程,或者把滑动的过程中出现的耗时操作延时到滑动停止后才开始
  • 分析滑动的过程中CPU的工作,看看是否能让CPU优先执行主线程的工作,尽量不要被其他线程抢占。

4.1  Traceview,寻找卡住主线程的地方

Traceview可以通过图形界面的方式让我们了解要跟踪程序的性能,并且能具体好每个函数的耗时和调用次数,所以我们主要是关注各个函数对性能的影响。一般来说,主要有两种类型的函数可能会影响到流畅度:

1)主线程里占用CPU时间(Incl Cpu Time)很长的函数,特别要留意在主线程的IO操作(文件IO、网络IO、数据库操作等)。

首先按CPU占用时间(Incl Cpu Time)降序排序,然后一个个去观察,找出哪些耗时的API在主线程上执行,再去看看代码,是否能移到非主线程执行,如果涉及IO操作看看能否做缓存。

2)主线程调用次数(包括被调用和递归调用)很多的函数。

4.2   Systrace,获取App运行时线程的信息以及API的执行情况

通过在函数前后插入Trace.beginSection(“MainActivity.OnCreate”)和Trace.endSection(),就能看到该函数的耗时和函数的调用关系

Systrace的优点:

1)能直观地看到每个线程上面API的调用情况,包括API的耗时以及API的调用顺序。2)能直观地看到每个线程的执行情况,包括各个线程的状态以及耗时,并且能够统计CPU里每个线程执行的耗时。3)能够通过插入代码的方式,在Systrace里显示想要查看的API的耗时以及调用关系。

4.3优化APP的IO层

IO分为网络IO和磁盘读写IO。在主线程进行长时间或者频繁的IO操作,对流畅度会有非常大的影响。

  4.3.1 我们通过代码注入(hook)的方式,hook文件打开关闭以及读写的API,采集磁盘IO的信息,IO信息包括读写的次数、读写的线程、读写数据的大小等。然后通过监控的结果来判断是否存在IO层的问题。

  4.3.2  Android提供的StrictMode

 

 

总结:

1、布局

     1.1 尽量多使用RelativeLayout和LinearLayout,不要使用绝对布局Absolute-Layout:a)在布局层次一样的情况下,建议使用          LinearLayout代替RelativeLayout,因为LinearLayout性能要稍高一点。b)在完成相对较复杂的布局时,建议使用                            RelativeLayout,RelativeLayout可以简单实现LinearLayout嵌套才能实现的布局。

   1.2将可复用的组件抽取出来并通过include标签使用。

    1.3 使用ViewStub标签来加载一些不常用的布局。

    1.4 动态地inflation view性能要比SetVisiblity性能要好。当然用VIewStub是最好的选择。

    1.5  使用merge标签减少布局的嵌套层次。

    1.6 去掉多余的背景颜色,减少过度绘制:a)对于有多层背景颜色的Layout来说,留最上面一层的颜色即可,其他底层的颜色都可以去掉。b)对 于 使 用Selector当 背 景 的Layout(比 如ListView的Item,会 使 用Selector来标记点击,选择等不同的状态),可以将normal状态的color设置为“@android:color/transparent”,来解决对应的问题。

    1.7 使用compound drawables:包含ImageView和TextView的LinearLayout可以使用compound drawable实现,这样更高效               (注:compound drawables是指包含图片的Textview)

    1.8  内嵌使用包含layout_weight属性的LinearLayout会在绘制时花费昂贵的系统资源,因为每一个子组件都需要被测量两次。           在使用ListView与GridView的时候这个问题显得尤其重要,因为子组件会重复被创建,所以要尽量避免使用Layout_weight。

2、针对ListView的性能优化

2.1 复用convertView:在getItemView中,判断convertView是否为空,如果不为空,可复用。

2.2 异步加载图片,item中如果包含有image,那么最好异步加载

2.3     快速滑动时不显示图片:当快速滑动列表时(SCROLL_STATE_FLING), item中的图片或获取需要消耗资源的view,可以不显示出来;而处于其他两种状态(SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL),则将那些view显示出来。

2.4 item尽可能地减少使用的控件和布局的层次。同时要尽可能地复用控件,这样可以减少ListView的内存使用,减少滑动时gc次数。ListView的背景色与cacheColorHint设置相同颜色,可以提高滑动时的渲染性能。

2.5 getView优化:ListView中getView是性能是关键,这里要尽可能地优化。getView方法中不能做复杂的逻辑计算,特别是数据库和网络访问操作,否则会严重影响滑动时的性能。

3、解放UI主线程

3.1 不要阻塞UI线程:占用CPU较多的数据操作尽可能放在一个单独的线程中进行,通过handler等方式把执行的结果交于UI线程显        示。特别是针对的网络访问、数据库查询和复杂的算法。目前Android提供了AsyncTask,Hanlder、Message和Thread的组合。    对于多线程的处理,如果并发的线程很多,同时有频繁的创建和释放,可以通过concurrent类的线程池解决线程创建的效率瓶颈。

3.2 不要在UI线程之外操作UI。

 

ps: 还是要去更深入的了解一下Android的相关知识,好多名词都不知道什么意思   ==

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值