Android性能优化

来源:互联网 发布:java float 比较大小 编辑:程序博客网 时间:2024/06/10 21:06

Android性能优化方案

布局优化

尽量减少layout层级,减少界面绘制的工作量。
采用,标签

自定义View的绘制

onDraw中不要创建大量的局部对象。因为onDraw方法会被频繁调用,这样就会在一瞬间产生大量的临时对象,不仅会占用过多内存还会导致系统频繁GC,降低程序执行效率。
onDraw中不要做太多耗时才操作。

内存优化

  • 静态变量导致的内存泄露
    示例:一个外部的静态Context变量引用了当前的Activity实例,当Activity销毁的时候无法被销毁。或者一个Activity的一个静态Context变量,引用了当前Activity,销毁之前没有释放,导致Activity无法被销毁。
    解决方法:不要将Activty作为Context传给外部Context变量。如果外部需要传入Context,可以使用Application Context,因为Application Context的生命周期与APP的生命周期一致。如果Activity内部有静态Context变量持有当前Activity实例,在onDestroy的时候要将该变量持有Activity释放。

  • 单例模式导致的内存泄露
    示例:单例模式内部的Context变量持有外部存入的Activity实例,在Activity销毁之前没有释放操作,导致Activity无法被销毁,内存无法回收。
    解决办法:如果单例模式需要Context的时候,可以通过调用Context.getApplicationContext()方法或者Activity.getApplication()方法来传入Application对象。或者直接在Application 创建的时候,即onCreate的时候传入Application Context。

  • 属性动画导致的内存泄露
    示例:属性动画中有一类无限循环的动画,如果在Activity播放了此类动画并且没有在onDestroy中去停止动画,那么动画会一直播放下去,并且这个时候Activity的View会被动画持有,而View又持有了Activity,最终导致Activity无法释放。
    解决办法:在Activity的onDrstroy中调用animator.cancel()来停止动画。

  • 自定义Handler导致的内存泄露
    示例:如果我们在Activity中定义一个非静态的Handler内部类,这样这个内部类就默认持有了当前Activity实例的引用。Handler常常伴随着一个执行耗时操作的异步线程(如下载多张图片),如果在完成耗时操作之前,Activity退出,异步线程持有handler的引用,handler持有Activity的引用,Activity的实例无法被销毁,从而导致内存泄漏
    解决办法:用一个静态的内部类的来代替,同时Weakference的方式传入外部Activity的引用。同时在Activity的onDestroy方法里面调用mHandler.removeCallbacksAndMessages(null);移除该Handler相关的消息队列中所有消息和所有的Runnable。

代码示例:

private MyHandler mHandler = new MyHandler(this);    private static class MyHandler extends Handler {        WeakReference<MainActivity> weakReference;        public MyHandler(MainActivity activity) {            weakReference = new WeakReference<MainActivity>(activity);        }        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    }
  • AsyncTask导致的内存泄露
    原因和Handler内存泄露原因相似,解决办法也一样,采用静态内部类的方式。

事例:

private MyAsyncTask asyncTask;    private static class MyAsyncTask extends AsyncTask<Void, Integer, String>{        public final WeakReference<MyActivity> weakReference;        public MyAsyncTask(MyActivity activity){            weakReference = new WeakReference<MyActivity>(activity);        }        @Override        protected String doInBackground(Void... params) {            //该方法中最好不要做一些不可中断的操作,否则的话。AsyncTask在cancel的时候是无法被停掉的。            //例如,BitmapFactory.decodeFile(...)等            return null;        }        @SuppressLint("NewApi")        @Override        protected void onPostExecute(String result) {            super.onPostExecute(result);            MyActivity myActivity = weakReference.get();            if (myActivity.isFinishing() || myActivity.isDestroyed()) {                //满足条件说明Activity正在销毁,此时不应该和UI进行交互。因为此时的Activity正在被销毁                return;            }else{                //通过软应该拿到的外部activity的引用和UI交互            }        }    }    @Override    protected void onDestroy() {        super.onDestroy();        //在onDestroy做如下判断,如果activity正在被销毁,则取消asynctask        if (asyncTask!=null && !asyncTask.isCancelled()) {            asyncTask.cancel(true);        }    }
  • 4.其他
    Bitmap对象使用完后,忘记了调用recycle()方法销毁;
1 0