Android性能优化_《Android开发艺术探索》

布局优化

首先删除布局中无用的控件和层级,其次有选择地使用性能较低的ViewGroup

在CPU的使用度上,RelativeLayout使用的时间比LinearLayout要多。因此,如果能使用LinearLayout的话,就不要使用RelativeLayout。不过大多数的时候,单独使用一种布局无法完成界面的部署,因此需要通过“嵌套”的方式来完成。

如果不得已使用嵌套布局的话,建议采用RelativeLayout,因为ViewGroup的嵌套就相当于增加了布局的层数,同样会降低程序的性能。

另外一种手段是采用<include>标签、<merge>标签和ViewStub

<include>标签主要用于布局重用

<merge>标签一般配合<include>配合使用,它可以降低减少布局的层级

ViewStub提供了按需加载的功能

<include>加载布局文件示例:


绘制优化

绘制优化是指onDraw方法要避免执行大量的操作。

  1. onDraw中不要创建新的局部对象。这是因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象。
  2. onDraw方法中不要做耗时的任务,也不能执行成千上万次的循环操作,这会造成View的绘制过程不流畅。

内存泄露优化

1、静态变量导致的内存泄露

在dalvik虚拟机中,static变量所指向的内存引用,如果不把它设置为null,GC是永远不会回收这个对象的。

public class MainActivity extends Activity{
	public static Context mContext;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContext = this;
	}
}

解决办法:在onDestroy()方法中将mContext = null; 处理。

2、单例模式导致的内存泄漏

public class SingletonA {
    private static SingletonA mSingletonA;

    public static SingletonA getInstance(){
        if (mSingletonA  == null) {
            return new SingletonA();
        }
        else
            return mSingletonA;
    }

    //constructor
    public SingletonA(){}
    //other methods
}

接下来在Activity中对这个类进行使用:

protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);
	SingletonA instanceF = SingletonA.getInstance(this);  
//在当前代码中使用this将此activity的实例给了静态变量,导致activity退出以后无法被释放
}  

3、属性动画导致的内存泄露

从Andorid 3.0开始出现属性动画,属性动画中有一类无限循环的动画,如果不在onDestroy中去停止动画,那么动画会一直播放下去,尽管已经无法在界面上看到动画效果了,并且这个时候Activity的View会被动画持有,而View又持有了Activity,最终Activiy无法释放。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mButton = findViewById(R.id.button);
    ObjectAnimator animator = ObjectAnimator.ofFloat(mButton,"rotation",0,360).setDuration(2000);
    animator.setRepeatCount(ValueAnimator.INFINITE);
    animator.start();
}

解决方法是在Activity的onDestroy中调用animator.cancel()来停止动画。

响应速度优化和ANR日志分析

Android规定,Activity在5秒内无法响应屏幕触摸事件或者键盘输入事件出现ANR。BroadcastReceiver在10秒内未执行操作会出现ANR。

定位ANR:在/data/anr目录下的文件traces.txt,通过分析这个文件能定位ANR的原因。

如下面的代码:

protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(Runnable.layout.activity_main);
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				testANR();
			}
		}).start();
		
		SystemClock.sleep(10);
		initView();
	}
	
	private synchronized void testANR(){
	}
	private synchronized void initView(){
	}

虽然testANR()和initView()不在同一个线程上,但是因为他们都要获取同一个对象的锁(this),因此也会发生子线程与主线程抢同一个锁的情况。

ListView和Bitmap优化

ListView:

1、首先要采用ViewHolder并避免在getView中执行耗时操作

2、其次要根据列表的滑动状态来控制任务的执行频率,比如当列表快速滑动时显然是不太适合开启大量的异步任务的。

3、尝试开启硬件加速来使ListView的滑动更加流畅。

线程优化

  • 避免创建过多的对象
  • 不要过多使用枚举,枚举占用的内存空间比整型要大
  • 常量请使用 static final 来修饰
  • 使用一些Android特有的数据结构,例如SparseArray 和 Pair 等,它们都具有更好的性能
  • 适当使用软引用和弱引用
  • 采用内存缓存和磁盘缓存
  • 尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄露
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值