1 应用UI卡顿常见原因
人为在UI线程中做轻微耗时操作,导致UI线程卡顿;
布局Layout过于复杂,无法在16ms内完成渲染;
同一时间动画执行的次数过多,导致CPU或GPU负载过重;
View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重;
View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染;
内存频繁触发GC过多(同一帧中频繁创建内存),导致暂时阻塞渲染操作;
冗余资源及逻辑等导致加载和执行缓慢;
臭名昭著的ANR;
1-0 应用UI卡顿分析解决方法
1-1 使用HierarchyViewer分析UI性能
1-2 使用GPU过度绘制分析UI性能
1-3 使用Lint进行资源及冗余UI布局等优化
1-4使用Memory监测及GC打印与Allocation Tracker进行UI卡顿分析
1-5 使用Traceview和dmtracedump进行分析优化
1-6 应用UI性能分析解决总结
布局优化;尽量使用include、merge、ViewStub标签,尽量不存在冗余嵌套及过于复杂布局(譬如10层就会直接异常),尽量使用GONE替换INVISIBLE,使用weight后尽量将width和heigh设置为0dp减少运算,Item存在非常复杂的嵌套时考虑使用自定义Item View来取代,减少measure与layout次数等。
尽量减少不必要的背景设置,图片尽量压缩处理显示,尽量避免频繁内存抖动等问题出现。
自定义View等绘图与布局优化;尽量避免在draw、measure、layout中做过于耗时及耗内存操作,尤其是draw方法中,尽量减少draw、measure、layout等执行次数。
避免ANR,不要在UI线程中做耗时操作,遵守ANR规避守则,譬如多次数据库操作等。
2 Android应用规避内存溢出OOM建议
时刻记得不要加载过大的Bitmap对象;譬如对于类似图片加载我们要通过BitmapFactory.Options设置图片的一些采样比率和复用等,具体做法点我参考官方文档,不过过我们一般都用fresco或Glide开源库进行加载。
有些地方避免使用强引用,替换为弱引用等操作。
避免各种内存泄露的存在导致OOM。
对于有缓存等存在的应用尽量实现onLowMemory()和onTrimMemory()方法。
尽量使用线程池替代多线程操作,这样可以节约内存及CPU占用率。
尽量管理好自己的Service、Thread等后台的生命周期,不要浪费内存占用。
尽可能的不要使用依赖注入,中看不中用。
尽量在做一些大内存分配等可疑内存操作时进行try catch操作,避免不必要的应用闪退。
尽量的优化自己的代码,减少冗余,进行编译打包等优化对齐处理,避免类加载时浪费内存
避免在Android中使用Java的枚举类型,因为编译后不但占空间,加载也费时
Handler发送消息时尽量使用obtain去获取已经存在的Message对象进行复用
在使用后台Service时尽量将能够替换为IntentService的地方替换为此,这样可以减轻系统压力、省电、省内存、省CPU占用率。
尽量减少锁个数、减小锁范围,避免造成性能问题。
合理的选择使用for循环与增强型for循环,譬如不要在ArrayList上使用增强型for循环等。
3 Android应用耗电量优化建议
在需要网络的应用中,执行某些操作前尽量先进行网络状态判断。
在网络应用传输中使用高效率的数据格式和解析方法,譬如JSON等。
在传输用户反馈或者下载OTA升级包等不是十分紧急的操作时尽量采用压缩数据进行传输且延迟到设备充电和WIFI状态时进行。
在有必要的情况下尽量通过PowerManager.WakeLock和JobScheduler来控制一些逻辑操作达到省电优化。
对定位要求不太高的场景尽量使用网络定位,而不是GPS定位。
对于定时任务尽量使用AlarmManager,而不是sleep或者Timer进行管理。
尽可能的减少网络请求次数和减小网络请求时间间隔。
后台任务要尽可能少的唤醒CPU,譬如IM通信的长连接心跳时间间隔、一些应用的后台定时唤醒时间间隔等要设计合理。
特殊耗电业务情况可以进行弹窗等友好的交互设计提醒用户该操作会耗用过多电量。