(一)布局优化
1,就是尽量减少布局文件的层级.
2,简单的布局能用1个LinearLayout搞定的,就不要用Relativelayout,因为Framelayout和LinearLayout都是一种简单高效的ViewGroup,Relativelayout功能比较复杂,相对来说,布局渲染要花费更多时间.
但若是需要嵌套LinearLayout时,能用Relativelayout就用Relativelayout代替.
3,使用include,merge标签引入布局,或者用Viewstub延时加载.
可以通过手机开发者里面的调试GPU过度绘制来检测布局是否需要优化
(二)绘制优化
绘制优化是指在View的onDrwa()方法里避免执行大量的操作.比如:
1,不要在onDrwa()方法中创建对象,因为onDrwa()频繁被调用,这样就会产生很多临时对象,这样不近耗内存,还会导致系统频繁GC,降低运行效率.
2,不要在onDrwa()方法中执行耗时操作.不停的执行onDrwa(),就会有很多耗时任务轮训,造成View绘制不流畅.
(三)线程优化
线程的创建和销毁都比较耗性能,所以线程的优化是采用线程池,线程池的优点:
1,避免了线程创建销毁带来的消耗
2,能够有效控制线程池的最大并发数,避免了大量的线程因互相抢占资源从而导致的阻塞现象.
(四)内存泄漏优化
当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏。
不停的内存泄漏,就会导致内存溢出.所以内存泄漏优化分为2个方面来解决:
A,代码中注意,
B,上线前通过LeakCanary、MAT等工具来检测
在敲代码时就要注意:
1,静态变量造成的内存泄漏,
public class TestActivity extends Activity {
public static Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
}
}
解决方式:变量不用static修饰,或者上下文用Application的上下文.
2,Handler容易造成内存泄漏,当使用内部类或匿名内部类的方式创建Handler时,Handler对象会隐式地持有一个外部类对象的引用(这里的外部类是Activity)。
一般在一个耗时任务中会开启一个子线程,如网络请求或文件读写操作,我们会使用到Handler对象。但是,如果在任务未执行完时,Activity被关闭了,Activity已不再使用,此时由GC来回收掉Activity对象。
由于子线程未执行完毕,子线程持有Handler的引用,而Handler又持有Activity的引用,这样直接导致Activity对象无法被GC回收,即出现内存泄漏。
public class TestActivity extends AppCompatActivity {
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//...
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
}
private void loadData(){
//...request
Message message = Message.obtain();
mHandler.sendMessage(message);
}
}
解决方式:
2.1,将Handler声明为静态内部类。因为静态内部类不会持有外部类的引用,所以不会导致外部类实例出现内存泄露。
2.2,在Handler中添加对外部Activity的弱引用。由于Handler被声明为静态内部类,不再持有外部类对象的引用,导致无法在handleMessage()中操作Activity中的对象,所以需要在Handler中增加一个对Activity的弱引用。
2.3,这样虽然避免了Activity泄漏,不过Looper线程的消息队列中还是可能会有待处理的消息,所以我们在Activity的Destroy时或者Stop时应该移除消息队列中的消息
public class TestActivity extends AppCompatActivity {
private MyHandler mHandler = new MyHandler(this);
private TextView mTextView ;
private static class MyHandler extends Handler {
private WeakReference<Context> reference;
public MyHandler(Context context) {
reference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
TestActivity activity = (TestActivity ) reference.get();
if(activity != null){
activity.mTextView.setText("");
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
3,资源未及时释放:
对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。
4,无限轮训动画造成泄漏:
解决方式:销毁时,取消动画
animator = ObjectAnimator.ofFloat(btn_home, "ratation", 0, 360).setDuration(2000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.start();
@Overrideprotected void onDestroy() { super.onDestroy(); animator.cancel(); }
(五)不要使用枚举,枚举占用的内存空间比整型大;使用一些特有的数据结构,比如AparryArray和Pair等,性能更佳.
借鉴资源:
1,任玉刚先生的安卓艺术开发探索
2,Android性能优化之常见的内存泄漏 https://blog.csdn.net/u010687392/article/details/49909477