15.1 Android的性能优化方案
(1). 2015年Google关于Android性能优化典范的专题视频Youtube视频地址
(2). 布局优化
1. 删除布局中无用的组件和层级,有选择地使用性能较低的ViewGroup,LinearLayout的复杂度小于RelativeLayout
2. 使用<include>
、<merge>
、<viewstub>
等标签;<include>
标签主要用于布局重用,<merge>
标签一般和<include>
配合使用,它可以减少布局中的层级;<viewstub>
标签则提供了按需加载的功能,当需要的时候才会将ViewStub中的布局加载到内存,提供了程序的初始化效率。
3. <include>
标签只支持android:layout_
开头的属性,android:id
属性例外。
4. ViewStub
继承自View,它非常轻量级且宽高都为0,它本省不参与任何的布局和绘制过程。实际开发中,很多布局文件在正常情况下都不会显示,例如网络异常时的界面,这个时候就没有必要在整个界面初始化的时候加载进行,通过ViewStub可以做到在需要的时候再加载。
<ViewStub android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/layout_network_error"/>
其中stub_import是ViewStub的id,而panel_import是layout/layout_network_error这个布局的根元素的id。当ViewStub通过setVisibility或者inflate方法加载后,ViewStub就会被它内部的布局文件替换掉,这个时候ViewStub就不再是整个布局结构中的一部分了。
(3). 绘制优化
1. 在onDraw
中不要创建新的布局对象,因为onDraw
会被频繁调用;
2. onDraw
方法中不要指定耗时任务,也不能执行成千上万次的循环操作。
(4). 内存泄露优化
可能导致内存泄露的场景很多,例如静态变量、单例模式、属性动画、AsyncTask、Handler等等。
(5). 相应速度优化和ANR日志分析
1. ANR出现的情况:Activity如果5s
内没有响应屏幕触摸事件或者键盘输入世界就会ANR,而BroadcastReceiver如果10s
内没有执行完操作也会出现ANR。
2. 当一个进程发生了ANR之后,系统会在/data/anr
目录下创建一个文件traces.txt
,通过分析这个文件就能定位ANR的原因。
(6). ListView和Bitmap优化
1. ListView优化:采用ViewHolder
并避免在getView
方法中执行耗时操作;根据列表的滑动状态来绘制任务的执行频率;可以尝试开启硬件加速来使ListView的滑动更加流畅。
2. Bitmap优化:根据需要对图片进行采样,具体详情看第十二章
(7). 线程优化
看第十一章
(8). 其他优化建议
1. 不要过多食用枚举,枚举占用的内存空间要比整型大;
2. 常量请食用static final
来修饰;
3. 食用一些Android特有的数据结构,比如SparseArray
和Pair
等,他们都具有更好的性能;
4. 适当食用软引用和弱引用;
5. 采用内存缓存和磁盘缓存;
6. 尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄露。
(9). MAT是功能强大的内存分析工具,主要有Histograms
和Dominator Tree
等功能。
(10). 提高程序的可维护性
1. 命名要规范,要能正确地传达出变量或者方法的含义,少用缩写,关于变量的前缀可以参考ANdroid源码的命名方式,比如私有成员以m开头,静态成员以s开头,常量则全部用大写字母表示,等等。
2. 代码的排版上需要留出合理的空白来区分不同的代码块,其中同类变量的声明要放在一组,两类变量之间要留出一行空白作为分区。
3. 仅为非常关键的代码添加注释,其他地方不写注释,这就对变量和方法的命名风格提出了很高的要求,一个合理的命名风格可以让读者阅读远吗就像阅读注释一样,因此根本不需要为代码额外写注释。