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个部分
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
2ActivityManager 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/LOGTraceView日志
- Incl CPU Time 某方法占用CPU的时间
- Excl CPU Time 某方法本身不包括子方法占用CPU的时间
- Incl Real Time 某方法真正执行的时间
- Excl Real Time某方法本身不包括子方法执行的时间
- Calls+RecurCalls 调用次数+递归回调次数
- 从Incl CPU Time和Calls+RecurCalls开始进行分析,如果占用时间长,Calls+RecurCalls次数少,就可以是怀疑对象了
-
- 手动查看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
8activity 显示所有Activity栈的信息
meminfo 内存信息
battery 电池信息
package包信息
wifi WiFi信息
alarm alarm信息
procstats 内存状态
grep,find 在性能优化bug分析时有用