Vary's Blog

Android面试之性能优化

性能优化

  1. 界面不流程,如何去debug调试View,来定位卡顿问题?
  2. 如何解决卡顿问题?
  3. xml编写和View写法是否合理?
  4. 移除不必要的背景图
    • window默认背景图
    • ListView设置背景后,item又设置了背景图
    • 多层嵌套,多次设置背景图
  5. 优化布局避免空间View树过高,空间重叠
  6. 自定义View的时候使用clipRect裁剪出需要绘制的区域绘制,已减少其他区域的绘制。

 可以通过Android SDK提供的Hierarchy View可量化的子View的总是和测量(measure)、布局(layout)、绘制(draw)所消耗的时间,以及View层级树的高度

 首先要明白的是UI的绘制流程:measure-layout-draw,measure与layout都需要for loop所有的子控件,汇集起来才能完成绘制,布局。所以子控件越多,所消耗的时间越长(inflate,layout_weight,relative,多层嵌套等),减少不必要的子控件或层级,是相当有必要的。你可以通过merge,viewstub这些标签来减少层级嵌套。如果你的空间观念没那么好,可以用HierarchyViewer工具来检查。

Mesure过程

  • 设置本View视图的最终大小
  • 如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。
  • measureChilren(),内部使用一个for循环对子视图进行遍历,分别调用子视图的measure()方法
  • measureChlid(),为指定的子视图measure,会被measureChildren调用
  • measureChildWithMargins(),为指定子视图考虑了margin和padding的measure。

Layout过程

  1. layout方法会设置该View视图位于父视图的坐标轴,即mLeft,mTop,mRight,mBottom(调用setFrame()函数去实现)
  2. 接下来回调onLayout()方法(如果该View是ViewGroup对象,需要实现该方法,对每个子视图进行布局)
  3. 如果该View是个ViewGroup类型,需要遍历每个子视图的childView,调用该子视图的layout()方法去设置它的坐标值

帧率

 在安卓中界面要看起来流畅,那么它的帧率是60,也就是说在1秒钟之内它会刷新60次,那么每次刷新的耗时也就是1000ms除了60,等于16.67ms.
 那么如果视图的刷新时间在16ms之内完成了,我们用起来就会觉得很流畅,那么假如因为某种原因,一个刷新过程没有在16ms之内完成,那么就会出现掉帧现象,也就是卡顿了。那么为了不出现这种掉帧现象,让用户用起来更流程,就需要尽量让一个绘制过程在16ms只能完成。
 这也就是性能优化所要最终完成的目标。Measure+Layout+Draw<=16ms.
 那么我们就只要看measure、layout、draw都干了那些事情,有哪些点是可以优化的,只要逐个的解决这些优化点,也就完成了一系列的View优化工作。

如何优化

从内优化(从View本身)

  • 尽可能少的使用margin,padding
    因为在测量绘制的过程中,会单独对已经设置过margin和padding的View进行另外多一步的操作,所有这个时候可以采用在父View中设置margin和padding来代替在子View中进行分别设置
  • 减少View层级
    这3个过程都涉及到循环遍历子View的过程,所有减少View的层级可以很好的加快循环遍历的过程
  • 去除不必要的背景
  • 去除不必要的scrollbar和不需要的效果
  • 慎用渐变

从外优化

  • 布局嵌套过于复杂
    这个会直接导致View的层级变多,然后测量绘制的效率变差
  • View的过度绘制
  • View的频繁重新渲染
  • UI线程中进行耗时操作

    在Android4.0其实是不允许ui线程中做网络操作了,那假如说你不小心做了写IO操作,而且他们又比较耗时,有可能会导致UI线程卡顿。View绘制阻塞

  • 冗余资源及错误逻辑导致加载和执行缓慢(其实就代码写的烂)
    比如你在getView()里去for循环,for循环里又for循环,又去声明变量之类的,都会导致代码的执行效率很差

  • 频繁触发GC,导致渲染受阻
    GC线程优先级高于UI线程,所有如果内存管理不够合理的话频繁的触发了GC,就会导致UI线程的受阻
Vary Zhao wechat
欢迎你扫描上面的二维码,加我微信