android应用性能优化之帧率

转自:http://www.cnblogs.com/myzh/archive/2013/03/17/2965225.html
   1、纵观全局
  对于顺畅度的分析,首先要知道一个整体情况,是局部,还是全局,这样在优化上才能有方向。
  如果是局部问题,那就需要仔细分析出具体的相关操作,如果是大体上的问题,那在思考的时候,就需要从整体的实现机制来考虑,有可能是实现方式上出现了问题。
  在android4.1中, 谷歌提供了一个工具来,叫做“ GPU呈现模式分析(Profile GPU rendering)”,在开启这个功能后,系统就会记录保留每个界面最后128帧图像绘制的相关时间信息。
  如果是在开启应用后才开启此功能,记得先把应用结束后重新启动。
  开启后操作你需要分析的部分(比如滑动列表之类的),然后执行adb命令
  $ adb shell dumpsys gfxinfo com.xxxx.xxx
  在执行的结果中,有一块叫做“Profile data in ms”底下有一堆数据.
  Draw:表示在Java中创建显示列表部分中,OnDraw()方法占用的时间。
  Process:表示渲染引擎执行显示列表所花的时间,view越多,时间就越长
  Execute:表示把一帧数据发送到屏幕上排版显示实际花费的时间。其实是实际显示帧数据的后台缓存区与前台缓冲区交换后并将前台缓冲区的内容显示到屏幕上的时间。所以这个时间,一般都很短。
  PS:View类包含Surface(变量名mSurface),每个Surface通常对应两个buffer,一个front buffer, 一个back buffer。(4.1之后是3个,一个前,两个后)其中,back buffer就是canvas绘图时对应的bitmap (研究Android_view_Surface.cpp::lockCanvas)。因此,绘画总是在back buffer上,需要更新时,则将back buffer和front buffer互换。
  Draw + Process + Execute = 完整显示一帧 ,这个时间要小于16ms才能保存每秒60帧。
  将数据复制到excel中(win记得逐列复制,mac下就直接复制过去吧),然后将数据生成“堆积柱形图”
  从图上看,能看出几个现象。第一,确实4.1的黄油项目还真的有点作用,每帧的时间控制在16ms左右。第二,有几帧超过16ms,确实会有丢帧的现象。
  看来,页面的卡顿应该是个别操作的问题。
   2、具体分析
  “GPU呈现模式分析”的数据只能说明个现象,比如上面提到的数据,能说明在实际运行中会有短暂的长时间绘制问题。但造成问题的具体原因并没有说明。
  而且“GPU呈现模式分析”显示的是最后128帧的数据,但丢帧也有可能是两帧之间存在长时间的操作而造成的。
  所以我们需要分析帧与帧之间的情况,才能对所分析应用的整体性能情况有个更升入的了解。
  在 android中提供了两个工具来达到这个目的:1、Systrace (这工具坑的我....等下再吐槽) 2、traceview
  Systrace是对整个系统进行分析,数据比较准确,当然也包括我们所要分析的应用。
  当这个工具的使用是有条件限制的:
  (1)是4.1之后才提供的工具。
  (2) 手机的内核一定要支持trace(可以查看是否存在/sys/kernel/debug/tracing 这个目录),所以很多第三方ROM或者三星之类的rom都在内核中remove了这个模块。模拟器里面好像也都没有。[这个坑的我刷了无数多的rom才找到适合的...之前的one x我记得好像也有,这个也间接说明一点,作为开发者,还是乖乖的买亲儿子好]
  Systrace的运行方式有两种,一种是运行sdk包下的py文件,这种要求的环境配置比较多。另一种就是在adt下的工具,点击直接运行。所以下面的使用介绍主要是这种。
  在流畅程度的这种特殊分析情景下,我们一般只关注图形性能。所以我们要选择Graphics和View.还有其他很多选项,如果是在做音频处理或者视频播放的分析 测试话,可以选择其他选项。
  确认运行之后,滚轮我们要测试的列表,工具会记录5秒钟的数据,之后我们回得到一个html页面。打开后,我们能看到页面中显示了系统中一切运行情况的概述。
  浏览的操作时通过WASD来完成,W/S 放大/缩小 A/D 左移/右移
  页面中有个surfaceFlinger,知道android绘制原理的人应该能明白,这个就是负责绘制Android应用程序UI的服务,所以surfaceFlinger能反应出整体绘制情况,一般正常情况都是连续的,如果出现空档,一种是没有操作或者滑动到头,没东西需要绘制,这种属于正常,另一种就是有问题存在,有其他操作时间过长。
  对应所要分析的程序那行,放大后就能看到具体的情况,点击后能看到每个部分所使用的时间。
  比如
  deliverInputEvent是系统提供的触摸事件。
  performTraversals是开始布局并且绘画显示画面的过程。
  draw是绘画的过程。
  ...
  对于一个listview,如果deliverInputEvent过长,很有可能是在adapter中的getView方法中处理时间过长导致。
  所以通过Systrace的数据,可以大体上的发现是否存在性能问题。
  但如果要知道具体情况,就需要用到另外一个工具。
  traceview
  这个工具其实比较简单,是一个分析器,记录了应用程序中每个函数的的执行时间。在DDMS中,选中要分析的进场,点击“Start method profiling”(就是右上角有个红点的图标)。然后开始操作要分析的应用,然后再次点击按钮来停止跟踪。
  然后下面显示的数据应该挺通俗易懂的。

  这里我想介绍下我使用的一个经验。
  ViewRootImpl.draw(),这个是绘制函数,点击后,绘制的部分就会被突出出来。从理论上讲,只要操作时没有太多停顿,draw()的图示应该是较为连续的。并且要保持顺畅,每一个draw区域应该在16ms及以下。
  所以一旦看到区域有大于16ms的,就可以认真分析下,看看都做了些什么操作。从而找到导致绘制时间过长的问题所在。
  对于这些工具的使用,虽然很大程度上能够帮助我们更快的定位到问题之处,但还是有许多局限的地方。
  如果对android整体系统原理有一定的理解,并且深刻知道自己的程序的运转情况,这样分析起来,才会炉火纯青。
  以上是我个人的一些看法,希望能帮助到大家,没写的太细,够用就好,因为有些部分,自己也有很多疑问,找到了一堆资料,发现也没有说明的特别详细的地方。

你可能感兴趣的:(android性能)