第15章 Android性能优化(笔记)

第15章 Android性能优化

为什么要性能优化?

Android设备作为一种移动设备,CPU和内存往往受到一定的限制。

  1. 过多的使用内存会导致内存溢出,即OOM(Out Of Memory)
  2. 过多的使用CPU会导致手机出现卡顿甚至出现无法响应的情况,即ANR(Application Not Responding)

一些有效的优化方法

  • 布局优化
    使用标签
  • 绘制优化
    在OnDraw()中一不要创建新的对象,二不要做耗时任务
  • 内存泄露优化
    养成良好的编程意识比如注意静态变量、单例模式和属性动画造成的内存泄漏
  • 相应速度优化
    避免ANR,比如不要再主线程里做超过5s的耗时任务,不要再onReceive里面做超过10s的任务,还要注意由于在主线程中等待长时间的同步锁而导致的ANR
  • ListView优化
    在Adapter中利用ViewHolder,在滑动时不要加载数据,开启硬件加速
  • Bitmap优化
    利用BitmapFactory.Options对象对图片进行压缩
  • 线程优化
    采用线程池从而避免大量的创建销毁线程,还能控制并发数避免阻塞现象
  • 其他优化
    • 避免创建过多的对象
    • 不要过多使用枚举
    • 常量使用static final修饰
    • 使用Android特有的数据结构比如SparseArray和Pair等
    • 适当使用软引用和弱引用
    • 采用内存缓存LreCache和磁盘缓存DiskLruCache
    • 尽量采用静态内部类

15.1 Android的性能优化方法

本节介绍了一些有效的性能优化方法。

15.1.1 布局优化

主要思想:布局中的层级少了,这就意味着Android的绘制工作少了,那么程序的性能自然就提高了。
主要方法:使用标签

标签

标签可以将指定布局加载到当前的布局文件中,通过layout属性来设置指定的布局文件,标签只支持带有android:layout_*这种属性,而且只要设定了相关属性,就必须存在android:layout_width和android:layout_height这两个属性。使用方法如下所示

    
标签

标签主要要和标签搭配使用,当标签的最外层布局和所处的当前布局一样时,比如说都是垂直方向的LinearLayout,此时便可以将标签的最外层布局的LinearLayout改成标签,如下所示


    
    

标签

标签主要是一个轻量级的按需加载的布局控件,特点是像标签一样包含一个布局文件,还有一个是可以在必要的时候显示和消失,所以ViewStub控件有利于显示一些网络加载或者异常时的界面。使用方法如下。
在布局文件中:


在代码中:需要注意的点就是上面inflatedId的理解,它的意思就是包含的根布局id,在上面的代码中就是titlebar.xml这个布局的id,然后通过该id可以获取到titlebar里的控件,比如下面的tvTitle

view = stub.inflate();
View titleBar = findViewById(R.id.titlebar_id);
tvTitle = (TextView) titleBar.findViewById(R.id.title);

btnSwitch.setOnClickListener(new OnClickListener() {
    
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        if(view.getVisibility() == View.VISIBLE)
            view.setVisibility(View.GONE);
        else
            view.setVisibility(View.VISIBLE);
            
    }
});

btnChange.setOnClickListener(new OnClickListener() {
    
    int i = 0;
    
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        tvTitle.setText("i = " + i++);
    }
});

15.1.2 绘制优化

绘制优化是指View的onDraw方法要避免大量的操作,主要体现在内存和CPU两个方面:

  1. onDraw中不要创建新的局部对象
    因为onDraw可能会被频繁的调用而导致大量的对象被创建,这会导致占用过多的内存从而频繁地gc;
  2. onDraw中不要进行耗时的操作
    频繁的耗时操作会占用CPU的时间大量的时间,导致程序卡顿

15.1.3 内存泄漏优化

内存泄漏:程序在销毁时,还有一些引用没有被释放,导致这些对象占用的内存无法被使用
解决方法:
在开发过程避免写出有内存泄漏的代码,以下是几种容易造成内存泄漏的原因

  • 静态变量导致的内存泄漏
  • 单例模式导致的内存泄漏
    需要在不需要时解除
  • 属性动画导致的内存泄漏
    所以使用属性动画一定要记得在不可见时取消动画

15.1.4 响应速度优化和ANR分析

响应速度优化的核心思想是避免在主线程做耗时的操作,将耗时的操作放在线程里执行。同时还要注意另一种不是很明显的造成ANR的原因:在主线程中长时间等待同步锁

15.1.5 ListView和Bitmap优化

ListView优化

ListView优化主要发生在Adapter的getView中,14章里有分析,这里总结一下

  1. 采用ViewHolder进行缓存并且避免在getView中执行耗时操作
  2. 在滑动时不要加载数据
  3. 尝试开启硬件加速
Bitmap优化

Bitmap优化主要是通过BitmapFactory的Options对象进行的
方法:利用Options先计算出采样率inSampleSize并返回给Options,最后通过改变的Options对图片进行压缩

15.1.6 线程优化

线程优化主要体现在避免大量的创建和销毁线程,因此线程优化的思想就是使用线程池。使用线程池的好处就是,可以重用线程避免创建和销毁大量线程,还可以控制并发数以避免阻塞

15.1.7 一些性能优化建议

  • 避免创建过多的对象
  • 不要过多使用枚举
  • 常量使用static final修饰
  • 使用Android特有的数据结构比如SparseArray和Pair等
  • 适当使用软引用和弱引用
  • 采用内存缓存LreCache和磁盘缓存DiskLruCache
  • 尽量采用静态内部类

15.2 内存泄漏分析之MAT工具

15.3 提高程序的可维护性

本节主要是讲Android的程序设计思想,主旨是如何提高代码的可维护性和可扩展性

代码风格

  1. 命名要规范
    私有成员以m开头,静态成员以s开头,常量则全部用大写字母表示等等
  2. 代码的排版上需要留出合理的空白来区分不同的代码块
  3. 仅为非常关键的代码添加注释,其他地方不注释

层次性

代码的层次性是指代码要有分层的概念,不要试图在一个方法或者一个类中去全部实现,而要将它分成几个自逻辑,然后每个子逻辑做自己的事情

扩展性

程序的扩展性要在写程序的过程中时刻考虑到,考虑着如果这个逻辑后面发生了改变那么需要做哪些修改,以及怎么样才能降低修改的工作量

设计模式

恰当地使用设计模式可以提高代码的可维护性和可扩展性,但是Android程序有性能瓶颈,因此要控制设计的度,设计不能太牵强

你可能感兴趣的:(第15章 Android性能优化(笔记))