Android Notes(Performance)

Performance optimization

布局
  • 人眼感觉流畅画面的帧数要达到40-60帧每秒
  • 在Android中,系统通过VSYNC信号触发对UI的渲染,重绘,需要16ms,其实就是1000ms中显示60帧,1000/60=16.67.如果不能在16ms完成绘制,就会丢帧,例如绘制耗时20ms,在16ms有VSYNC信号时无法绘制,该帧被丢弃,等待下次信号才开始绘制,导致16*2ms 都显示同一帧画面
  • 在开发者选项中有Profile GPU Rendering 选中On Screen as bars,中间的绿色横线代表VSYNC时间16ms柱状线包含3个部分
    • 蓝色代表测量绘制Display List的时间
    • 红色代表OpenGL渲染Display List的时间
    • 黄色代表CPU等待GPU处理的时间
      Android 6.0
  • Overdraw
    Enable GPU Overdraw 查看当前区域绘制次数,增大蓝色区域,减少红色区域

    • 移除不需要背景
    • 减少布局层级,降低view树高度,不应超过10层

      1
      2
      <include> 布局中不设置宽高具体值(0dp)
      <ViewStub> 延时加载,可以使用setVisibility(),inflate()显示View,之后ViewStub就不存在了,被显示的layout代替,不能inflate两次,而View.GONE会在初始化布局的时候就已经添加在布局树中,相比之下ViewStub更有效率
    • 减少使用透明度alpha(会先绘制有颜色,再设置透明度)

    • hierarchy viewer
    1
    2
    3
    4
    "Tools" menu > Android > Android Device Monitor
    In ADM: "Window" Menu > Perspective
    Click on Hierarchy Viewer.
    Profile Node:Obtain layout times at the top of the Tree View
内存
  • 内存太低出发LMK(Low Memory Killer)
  • 手机内存指RAM,包括

    1
    2
    3
    4
    5
    寄存器(Registers)  位于处理器内部,速度最快,程序无法控制
    栈 存放基本类型的数据和对象的引用,对象本身不存放在栈中,而是存放在堆中
    堆 存放对象和数组,堆中分配的内存由Java虚拟机的回收器GC来管理
    静态存储区域 存放应用程序运行时一直存在的数据,如静态的数据变量
    常量池 常量的有序集合,包括基本类型,String和对其他类型,字段,方法的符合引用
  • 当定义一个变量,会在栈中分配内存空间,作用域结束后,会立即被用作新的空间分配。当new一个变量,在堆中分配内存空间,该对象作用域结束后,内存也不会立即回收,等待系统GC回收,内存分析就是分析Heap中的内存状态

    1
    2
    ActivityManager am=getSystemService(Context.ACTIVITY_SERVICE);
    int heapSize=am.getLargeMemoryClass();
  • 获取系统内存信息

    1
    adb shell dumpsys procstats
  • 内存监视,Settings-Apps-Running

    1
    adb shell dumpsys meminfo
  • Bitmap优化

    • 列表页面使用缩略图,低质量图片
    • 使用完Bitmap,使用bitmap.recycle()释放资源,Android3.0后Bitmap存放在堆内存中,内存由GC管理,不需要进行释放了
    • 使用内存缓存(LruCache)和硬盘缓存(DiskLruCache)可以更好使用Bitmap
  • 代码优化
    • 常量使用static修饰符
    • 静态方法比普通方法提高15%左右访问速度
    • 减少不必要的成员变量
    • 减少不必要的对象,使用基础类型比使用对象更加节省资源
    • 尽量不适应枚举,少使用迭代器
    • 对Cursor,Receiver,Sensor,File 非常注意对他们的创建,回收,注册,解注册
    • 避免使用IOC框架,IOC通常使用注解,反射实现
    • 使用RenderScript,OpenGL来进行非常复杂的绘图操作
    • 使用SurfaceView 来代替View进行大量的绘图操作
    • 尽量使用绘图缓存,而不是inflate()方法解析视图
工具分析优化
  • Lint 工具优化代码
  • Android Profile 监测CPU,Memory,Network
  • TraceView 优化App

    • Debug类开启TarceView

      1
      2
      3
      4
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
      onCreate()->Debug.startMethodTracing()
      onDestory()->Debug.stopMethodTracing()
      adb pull /sdcard/trace_log.trace/local/LOG
    • TraceView日志

      • Incl CPU Time 某方法占用CPU的时间
      • Excl CPU Time 某方法本身不包括子方法占用CPU的时间
      • Incl Real Time 某方法真正执行的时间
      • Excl Real Time某方法本身不包括子方法执行的时间
      • Calls+RecurCalls 调用次数+递归回调次数
      • 从Incl CPU Time和Calls+RecurCalls开始进行分析,如果占用时间长,Calls+RecurCalls次数少,就可以是怀疑对象了
    • MAT

      • 手动查看Heap,判断是否有内存泄漏小技巧:不停点击Cause GC,如果data object的total size有明显变化,就可能有内存泄漏
      • 点击Dump HPROF File,生成.hprof,然后再使用命令转换
        1
        hprof-conv com.willkernel.app.audiobar.hprof heap.hprof
    • Dumpsys分析系统状态
      1
      2
      3
      4
      5
      6
      7
      8
      activity 显示所有Activity栈的信息
      meminfo 内存信息
      battery 电池信息
      package包信息
      wifi WiFi信息
      alarm alarm信息
      procstats 内存状态
      grep,find 在性能优化bug分析时有用
willkernel wechat
关注微信公众号
帅哥美女们,请赐予我力量吧!