一、性能问题分类
- 1.内存问题:
耗内存、OOM、程序切换到后台后占用内存无法释放(OOM会影响产品的稳定性;耗内存、内存泄露会影响整机的性能;占用内存多预示着留给其它应用的剩余内存空间小);
- 2.功耗问题
发烫(耗电)
- 3.流畅度问题
启动慢、页面显示需要长时间转圈加载、页面切换卡顿、黑白屏(卡慢崩会让人烦躁);
针对上面一系列的性能问题,谷歌官方提供了各种各样的工具来针对性的解决各个方面的问题,也有很多不错的第三方工具值得尝试:
内存问题:提供了Android Studio的静态代码检测功能、Android Monitor;第三方内存泄露分析工具Leakcanary、MAT;
功耗问题:提供了GPU呈现模式、battery-historian、Android Monitor;
流畅度问题:提供了Android Studio的静态代码检测功能、Android Monitor、HierarchyViewer、StrictMode、过渡绘制检测工具、TraceView等;
二、性能优化指标
- 流畅度:FPS,即Frams per Second,一秒内的刷新帧数,越接近60帧越好;
- 启动时间:时间,越短越好;
- 内存泄露:AS静态代码检测结果、MAT检测结果,内存泄露很难用数值定义,但可以通过将优化前后工具检测的结果对比得出结论。没有内存泄露最好;
- 内存大小:峰值,峰值越低越好;
- 功耗:单位时间内的掉电量,掉电量越少越好;
从上面各项性能指标的定义可以看出,性能优化效果的评估主要是通过对比得出来的,性能如何只是相对的。只要针对同一个应用的同一项指标,优化后比优化前更优,就说明优化是有效果的。
三、性能优化原则和方法
1.流畅度问题
主要是界面过度绘制问题
优化方法
- merge
作为根目录减少层级 原理是减少根目录Framlayout的绘制 - viewStub
加载页面时不绘制该布局
原理是重写onDraw方法并被置空,onMeasure方法也没有实现 从而不绘制 而是在需要显示的时候显示(inflate) - Space
加载页面时不绘制布局
原理同viewStub类似 但是他是绘制尺寸大小的 有自己的宽高 - 去掉多余的背景
一般的activity都有个主题 它会为activity的window设置背景,再为activity设置背景显然会多绘制一次
原理是减少一层背景的绘制 - clipRect可以解决只刷新固定区域的问题;
- 不必要的alpha值设置可以解决同一视图被多次绘制的问题;
- 最重要的是产品设计合理,多和产品、UI沟通,避免无意义的工作
==说明==:
1、在主题中去掉Window的背景时要注意,去掉之后必须重新运行程序检查一下,避免有些Activity并没有设置背景导致界面背景为黑色;
2、有的程序为了避免冷启动时界面黑屏/白屏的问题,在主题中为window设置了一张图片,然后在布局文件中为Activity也设置了背景,这样既会导致过渡绘制问题,还会导致内存问题(同一个页面两张全屏的图片,双倍内存);所以这种解决方式并不妥,如果是启动速度问题,直接优化启动速度比这种方式靠谱。
2.内存优化
工具:
Android Studio提高代码质量必杀技:Inspact Code LeakCanery
- 非静态内部类导致的内存泄漏:
比如Handler,解决方法是将内部类写成静态内部类,在静态内部类中使用软引用/弱引用持有外部类的实例
-IO操作后,没有关闭文件导致的内存泄露
比如Cursor、FileInputStream、FileOutputStream使用完后没有关闭,这种问题在Android Studio 2.0中能够通过静态代码分析检查出来,直接改善就可以了;
-自定义View中使用TypedArray后,没有recycle,
这种问题也可以在Android Studio 2.0中能够通过静态代码分析检查出来,直接改善就可以了;
-某些地方使用了四大组件的context,在离开这些组件后仍然持有其context导致的内存泄露
1、启动Activity在这些类中是可以的,但是需要创建一个新的task,一般情况不推荐;
2、在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用;
3、在Receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视);
属性动画导致的内存泄漏
google提供的一种无限循环的属性动画 在activity销毁是 需要先将动画关闭
加载图片导致的内存问题
这个问题遵循以下原则就可以了:
1、UI只提供一套高分辨率的图,图片建议放在drawable-xxhdpi文件夹下(放在xxxhdpi或者更高分辨率的文件夹下没有必要,权衡利弊,照顾主流设备即可),这样在低分辨率设备中图片的大小只是压缩,不会存在内存增大的情况;
2、涉及到桌面插件或者不需要缩放的图片,放在drawable-nodpi文件夹下,这个文件夹下的图片在任何设备上都是不会缩放的。