android性能优化

    android设备作为一种移动设备,不管是内存还是CPU的性能都收到了一定的限制,无法做到像PC设备那样具有超大的内存和高性能的CPU。鉴于这一点,这也意味着android程序不可能无限制的使用内存和CPU资源,过多的使用内存会导致程序内存溢出,即OOM。而过多的使用CPU资源,一般是指做出大量的耗时任务,会导致手机变的卡顿无法响应的情况,即ANR。

  1. 布局优化

    布局优化的思想其实很简单,就是尽量减少布局文件的层级。
    
  • 进行布局优化,首先删除布局中无用的控件和层级,其次有选择的使用性能较低的viewGroup,比如RelativeLayout。如果布局中既可以使用LinearLayout也可以使用RelativeLayout,那么就采用LinearLayout,这是因为RelativeLayout功能比较复杂,它的布局过程需要花费更多的CPU。
  • 布局优化的另一种手段就是采用 < include>标签、< merge>标签和ViewStub.
    < include> 标签可以将一个指定的布局文件加载到当地的文件中。需要注意的是,如果在布局文件中的根元素中设置了ID,而在< include>也设置了id,以标签中的属性为准。
    < merge>标签一般和< include>标签一起使用从而减少布局的层级。如果当前布局文件中存在一个LinearLayout,而被包含的布局文件中也使用了LinearLayout,那么显然被包含的是多余的,通过< merge>标签可以去掉多余的这一层LinearLayout。
    ViewStub继承了View,它非常轻量级而且宽、高都是0,因此它本身不参与任何的布局绘制过程。ViewStub的意义在于按需加载所需的布局文件,在实际开发中,很多布局文件不会在正常情况不会显示,比如网络异常的界面,这个时候就没必要在初始化的时候,就把该界面加载进来,通过ViewStub就可以做到在使用的时候再加载,提高了程序初始化的性能。
  <ViewStub
        android:id="@+id/stub_import"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/layout_network_error"
        />

以下面两种方式进行:

findViewById(R.id.stub_impout).setVisibility(View.VISIBLE);

当ViewStub通过setVisibility方法加载后,ViewStub就会被它内部的布局替换掉,这个时候ViewStub就不再是整个布局结构中的一部分了。另外,目前ViewStub还不支持< merge>标签。

  1. 绘制优化
    绘制优化是指View的onDraw方法要避免执行大量的操作,这主要体现在两个方面。
  • 首先,onDraw中不要创建新的局部现象,这是因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,这不仅占用了过多的内存而且还会导致系统更加频繁GC,降低了程序的执行效率。
  • onDraw方法中不要做耗时的任务,也不能执行成千上万的循环操作,尽管每次循环都很轻量级,但是大量的循环仍然十分抢占CPU的时间片,这会照成View的绘制的不流畅。按照Google官方给出的性能优化典范中的标准,View的绘制帧率保证60fps都是最佳的,这就要求每帧的绘制时间不超过16ms(16ms = 1000/60),虽然程序很难保证16ms这个时间,但是尽量降低onDraw方法的复杂度总是切实有效的。
  1. 内存泄露优化
  • 内存泄漏
    3.1 静态变量导致的内存泄漏
        下面代码引用了静态mContext,导致Activity不能正常销毁,导致内存泄漏。
		public class MainActivity extends Activity {
		    private static final String TAG = "MainActivity";
		    private static Context context;
		    @Override
		    protected void onCreate(Bundle saveInstanceState){
		        super.onCreate(saveInstanceState);
		        setContentView(R.layout.activity_main);
		        context = this;
		    }
		}

   3.2 单例模式导致的内存泄漏
      静态变量导致的内存泄漏都比较明显,相应的单例模式带来的内存泄漏是容易让我们忽视的。
示例代码如下:

public class SingleInstance {
    private Context mContext;
    private static SingleInstance instance;
 
    private SingleInstance(Context context) {
        this.mContext = context;
    }
 
    public static SingleInstance getInstance(Context context) {
        if (instance == null) {
            instance = new SingleInstance(context);
        }
        return instance;
    }
 
    public void say() {
        Log.i("tag", "this is single instance");
        Log.i("tag", ":code:" + instance.hashCode());
    }

很明显的原因在于引用的context对象,当在程序中被activity调用了,恰巧activity先被销毁的情况下,因为一直在被static所修饰的类引用,会造成内存中不能被销毁,导致内存泄漏。
解决办法是可以将应用的ApplicationContext赋值给SingleInstance 的Context

public static SingleInstance getInstance(Context context) {
        if (instance == null) {
            instance = new SingleInstance(context.getApplicationContext());
        }
        return instance;
    }

   3.3 属性动画导致的内存泄漏
      从android3.0开始,Google提供了属性动画,属性动画中有一类无限循环的动画,如果在activity播放此类动画且没有在onDestory中去停止动画,那么动画会一直播放下去,尽管已经无法在界面上看到动画效果了,并且这个时候Activity的View会被动画持有,而View又持有了Activity,最终Activity无法释放。
4. 响应速度优化
      响应速度优化的核心思想是避免主线程中耗时操作。android中规定,activity如果5秒钟10秒钟之内还未执行完操作也会出现ANR。
5. 线程优化
      线程优化的思想就是线程池,避免程序中存在大量的Tread。线程池可以重用内部的线程,从而避免的线程的创建和销毁带来的性能开销,同时线程池还能有效的控制线程池的最大并发数,避免大量的线程因相互抢占资源从而导致阻赛现象的对象。
6. 电池电量优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值