因为这个是面试必问的,在这做再一次的总结,希望能帮助到大家和我自己。
我觉得性能优化除了掌握必要的技术外,关键是细心,不厌其烦。
一、布局优化
-
删除布局中无用的控件和层次
FrameLayout好过LinearLayout好过RelativeLayout。能用一个控件完成不用两个控件 -
避免过度绘制
在多层次重叠的UI结构里面,如果不可见的UI也在做绘制操作,会导致某些像素区域被绘制了多次,这个主要是针对背景,在setBackground时看下是否多余
二、绘制优化
主要针对自定义View的onDraw方法要避免执行大量的操作
-
不要创建新的局部对象
如Paint能在初始化创建就不放到onDraw - 不要做耗时的任务,也不能执行成千上万次的循环操作
三、内存泄漏优化
首先关于内存泄漏的理解:外部人为原因,无意识地持有对象引用,使得持有引用者的生命周期大于被引用者的生命周期
理解这话是关键,如我有静态变量,静态变量的创建需要context,这时我传了Activity的context,静态变量是和进程同样的生命周期,那是不是就算Activity关闭了,因为静态变量持有它,而导致它所占的内存就没办法被回收,也就任务内存泄漏
常见引发内存泄漏的原因:
1.集合类
虽然我不太认同集合类可以造成内存泄漏,但是如何集合元素对象是fragment或者activity,最好做下处理,进来在本界面操作。在合适的地方可以
// 释放objectList
objectList.clear();
objectList=null;
2.单例或者静态变量造成的内存泄漏
这个确实会,最好不引用任何对象,或者尽量找些生命周期比引用者生命周期长。Application里面找,或者同是静态变量
3.匿名内部类或者非静态内部类
其实是外部类中 持有 非静态内部类的静态对象,不过一般我们很少写这样的代码。
// 背景:
a. 在启动频繁的Activity中,为了避免重复创建相同的数据资源,会在Activity内部创建一个非静态内部类的单例
b. 每次启动Activity时都会使用该单例的数据
public class TestActivity extends AppCompatActivity {
// 非静态内部类的实例的引用
// 注:设置为静态
public static InnerClass innerClass = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 保证非静态内部类的实例只有1个
if (innerClass == null)
innerClass = new InnerClass();
}
// 非静态内部类的定义
private class InnerClass {
//...
}
}
// 造成内存泄露的原因:
// a. 当TestActivity销毁时,因非静态内部类单例的引用(innerClass)的生命周期 = 应用App的生命周期、持有外部类TestActivity的引用
// b. 故 TestActivity无法被GC回收,从而导致内存泄漏
自己感受写这例子就好
还有Hanlder,AsyncTask,Thread引起的内存泄漏也属于这类
解决方案:把内部类改为静态声明的
4.资源未关闭造成的内存泄漏
四、响应速度优化
避免在主线程中做耗时操作
如果有耗时操作,可以开启子线程执行,即采用异步的方式来执行耗时操作
五、线程优化
避免直接new Thread的做法,用线程池或者其他的
网友评论