您的位置:首页 > 移动开发

Android中app卡顿原因分析示例

2015-07-29 14:14 218 查看
http://www.cnblogs.com/zhucai/p/weibo-graphics-performance-analyse.html

朱才

专注于Android图形动画 MIUI工程师

博客园
首页
新闻
新随笔
联系
管理
订阅

随笔- 21 文章- 0 评论- 164

Android中app卡顿原因分析示例

在知乎回答了一个“为什么微博的app在iPhone比Android上流畅”的问题。后面部分是一个典型的动画卡顿的性能分析过程,因此帖在这里。有编程问题可以在这里交流。知乎链接

=========================================================

我来说下我所知道的事情。我不知道iOS为什么流畅,但我知道一些Android为什么不流畅的原因。

首先,就题主所说的问题,我用iPad和小米Pad对比了一下微博滑动滚屏这件事情(2014年8月10日目前微博app最新版本)。正如题主所说,直观感受上明显感觉iOS要流畅、舒服。

在这件事情上我认为主要是这三个原因:

速度曲线。

当你滑动界面然后松手,这时界面会继续滑动,然后速度减小,直到速度为0时停止。iOS下速度减小的这个过程比较慢,尤其是快要停的时候是慢慢停的,视觉上有种很顺滑的感觉;Android下则从松手到停要快很多,相比之下有种戛然而止的感觉。

从数据/技术角度来看这个事情,我们滑动界面的最终目的不是为了“动”,而是为了“停”,因此只要平滑的到达目的地,似乎越快完成这个过程越好,所以Android的选择是理所当然的。但事实是,大家普遍更喜欢iOS的方式,这样做显得更顺滑、更优雅。
帧率。

绝大部分时间两者都能保持60FPS左右的满帧率。但都会有偶尔的掉帧。并且Android上要比iOS上严重很多。(好吧,比起前两年,已经好太多了。)我前前后后滑动了几十次,iOS在前面遇到1次掉帧,后面就很稳定了。而Android几乎每滑动一次都会伴随一次掉帧。这完全就是真真实实的卡顿,用户必然会感觉到那一刻的不流畅。Android掉帧的原因我后面再详细分析。
触摸响应速度。

从手指碰到触摸屏,到屏幕上显示处理这次触摸产生的画面,是需要时间的。时间越短感觉越跟手。据说iOS的触摸屏的处理时间要比一般的Android手机快,这不是我的专长,不知道怎么验证。但在软件系统层面,Android的显示机制是app-->SurfaceFlinger-->Display,这比传统的app-->Display多了一步,主要基于这个原因,画面最终输出到屏幕要比传统的方式慢一帧(16.7ms)。

我觉得第1点造成的影响最大,恰恰却是最技术/设备无关的。如果微博app或者Android系统要改变,很容易就可以调得跟iOS一模一样。但正是由于这是产品形态上的差别而不是纯粹技术上的优劣,反倒成了Android最不太可能改变的。

第2点的影响其次,当然是指在目前这个大部分时候都能满帧的情况下。这方面是Android从早期到现在进步最明显的方面,使用了很多方法来优化帧率。但就算现在Android进化了很多,硬件性能也进化了很多,却仍旧不可能彻底消灭掉帧的情况。

第3点通俗的讲就是跟手性,跟手性的重要性不言而喻,但现在的差别比较细微,且具体数据我也不清楚。

我想过一个办法让桌面、微博这种内容和手一起动的应用绘制到屏幕的速度快一帧(16.7ms),其实就是抵消之前提到的慢的那一帧,需要framework层和app层一起配合改动,目前已申请了专利但代码还没进,将来有时间了应该会进到MIUI。感兴趣的可以看看专利:滑动操作响应方法、装置及终端设备

最后我来用专业技术分析一下微博app在Android里掉帧的原因。非编程人员可以不看下去了。(这个过程我使用的是小米3高通版+最新版微博app。)

最初,我认为这种现象很像GC(垃圾回收)导致的,于是打开logcat观察每次卡顿的时候有没有GC发生。结果发现并没有。停下来的时候才会有GC,这说明微博app在滑动过程中控制得不错,在停下来的一刻才去分配内存,使GC不影响帧率。

然后我打开“开发者选项”->“GPU呈现模式分析”->“在屏幕上显示为条形图”(好像是4.4才有这个选项,之前的只能在dumpsys里看),这会在屏幕上直观的显示每帧绘制花费的时间。屏幕上有条基准线大概是16ms,如果超过这条线则很有可能掉帧了。如果下面的蓝色部分很长则说明是软件draw的部分太费时,那么可以通过traceview来继续分析draw的java代码。(我假定了现在的app都是硬件加速的方式。)如果中间红色部分很长则说明是OpenGL ES绘制过程太费时。可以用gltrace来分析OpenGL ES的调用过程。

打开选项后使用微博app,发现虽然偶尔有超基准线,但并不严重,并且卡顿的时候并没有明显异常。

于是我开始使用systrace,这下就很明显了:



可以发现每隔几帧,就会有一次大间隙,图中我圈了红圈圈的两个地方都明显超过正常的耗时时间。现在问题是,这些地方的代码在干什么呢?是什么花费了这么长时间?



放大后发现都是这两个:obtainView和setupListItem。它们都是在draw之前调用的,这也解释了通过上一步的方法(“GPU呈现模式分析”)为什么没有显示出来,因为那个方法只展示draw里面的时间消耗。

通过在源码里搜索obtainView和setupListItem,可以发现是AbsListView的obtainView方法和ListView的setupChild方法打下的这个log。

接下来,我们用traceview来看看这两个方法里面究竟调用了什么代码导致耗时过长。

跟踪obtainView最终到了这里:



代码混淆了,看不太出来了,也懒得再跟下去了。但随便点了点然后看到:



TextView.setText用了挺多的时间。感觉Android团队应该优化优化这个方法。

然后再来跟踪setupChild方法:



都是measure占用的时间,并且调用次数比较多。这应该说明了View的数量不少。用hierarchyviewer看了下,的确不少,一条微博有50多个View:



结论:我们最终大致找到了耗时的代码及部分原因。这两个耗时方法应该都是有可能减下来的,但应该不那么容易。

在Android上实现功能比较容易,但如果默认实现有了性能问题,要想解决就不好说了,有时候要绕很远。

最后,列一些相关链接:

Android图形架构(绘图慢一帧的事情这里有说):http://source.android.com/devices/graphics/architecture.html

Android Performance Case Study:http://www.curious-creature.org/docs/android-performance-case-study-1.html

转载需注明出处:http://cnblogs.com/zhucai/

我的微博:http://weibo.com/zhucai

标签:
android,
graphics,
performance

绿色通道:好文要顶关注我收藏该文与我联系





朱才

关注 - 1

粉丝 - 18

荣誉:推荐博客
+加关注

0
0
(请您对文章做出评价)

«
上一篇:二维坐标图

»
下一篇:MIUI 6的毛玻璃效果的技术实现(实时模糊)

posted @ 2014-08-10 17:38
朱才 阅读(7529) 评论(2)

编辑
收藏

发表评论

回复引用
#1楼
2015-02-13 10:17 |
Elta


昨天看到了你的这篇博文,想和你说一下我在使用应用的时候发现的一个卡顿现象。

软件:Adobe reader

具体现象:在看PDF文件时,食指按住屏幕上下滑动,一开始的时候很流畅,在不松开手指的情况下反复上下滑动,开始出现卡顿现在。用手机带的条形图没有发现有掉帧。不会再向下分析了,很好奇这是什么原因导致的,是否有办法规避这个问题呢?
支持(0)反对(0)

回复引用
#2楼[楼主]
2015-03-03 08:51 |
朱才


@Elta

那可以估计出是绘图之间的时间导致的。可以用systrace来继续分析。
支持(0)反对(0)

刷新评论刷新页面返回顶部

发表评论

昵称:

评论内容:













注销
订阅评论
[使用Ctrl+Enter键快速提交]

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库

【热门】支持Visual Studio2015的葡萄城控件新品发布暨夏季促销

最新IT新闻:

· 禁令解除:国内主机游戏就能复活?

· 高通取得无线充电技术新突破:支持金属机身手机

· Twitter盘后大跌12% 临时CEO言论吓坏投资者

· 在线超新星搜寻项目启动 在家就能搞科研

· 希腊前财政部长承认授权侵入国家税收数据库

»
更多新闻...

最新知识库文章:

·
通过心理学知识提高问题定位与解决能力(上)

· 用医生的思考方式调试你的代码

· 代码审查的价值——为何做、何时做、如何做?

· 所有程序员都应该遵守的11条规则

· RESTful架构详解

» 更多知识库文章...

昵称:朱才

园龄:6年3个月

荣誉:推荐博客

粉丝:18

关注:1
+加关注

<2015年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

搜索

常用链接

我的随笔
我的评论
我的参与
最新评论
我的标签
更多链接

我的标签

android(4)
canvas(3)
graphics(3)
html5(2)
LambdaParser(2)
delegate(2)
js(2)
json(1)
Lambda(1)
DataContractJsonSerializer(1)
更多

随笔档案

2015年7月 (1)

2014年12月 (2)

2014年8月 (1)

2011年10月 (1)

2011年2月 (1)

2010年8月 (1)

2010年7月 (2)

2010年6月 (1)

2010年5月 (2)

2010年1月 (1)

2009年12月 (1)

2009年10月 (2)

2009年7月 (1)

2009年6月 (1)

2009年5月 (3)

链接

我的微博

最新评论

1. Re:Android中app卡顿原因分析示例
@Elta那可以估计出是绘图之间的时间导致的。可以用systrace来继续分析。...
--朱才
2. Re:Android中app卡顿原因分析示例
昨天看到了你的这篇博文,想和你说一下我在使用应用的时候发现的一个卡顿现象。软件:Adobe reader具体现象:在看PDF文件时,食指按住屏幕上下滑动,一开始的时候很流畅,在不松开手指的情况下反复上......
--Elta
3. Re:MIUI 6的毛玻璃效果的技术实现(实时模糊)
framework层?
--专注-
4. Re:动态计算表达式
好厉害 举一反三哇
--z5337

阅读排行榜

1. C#与Java的比较(17406)
2. Android中app卡顿原因分析示例(7529)
3. 用HashSet代替List(6034)
4. js中用gb2312编码解码(4858)
5. 我开发的几个chrome扩展(3901)

评论排行榜

1. 我开发的几个chrome扩展(38)
2. C#与Java的比较(17)
3. 用HashSet代替List(16)
4. out参数的失控(13)
5. LambdaParser:解析代码字符串为Lambda表达式并编译为委托(13)

推荐排行榜

1. 乒乓球的运动模拟(7)
2. LambdaParser的实现(4)
3. C#与Java的比较(4)
4. 我开发的几个chrome扩展(3)
5. 动态计算表达式(3)

Copyright ©2015 朱才
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: