美文网首页
第15章 Android性能优化(笔记)

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

作者: 反复横跳的龙套 | 来源:发表于2016-06-10 17:40 被阅读126次

    第15章 Android性能优化

    为什么要性能优化?

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

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

    一些有效的优化方法

    • 布局优化
      使用<include>、<merge>和<ViewStub>标签
    • 绘制优化
      在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的绘制工作少了,那么程序的性能自然就提高了。
    主要方法:使用<include>、<merge>和<ViewStub>标签

    <include>标签

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

        <include layout="@layout/titlebar"/>
    
    <merge>标签

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

    <merge xmlns:android="http://schemas.android.com/apk/res/android">
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Title"/>
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Content"/>
    </merge>
    
    <ViewStub>标签

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

    <ViewStub 
        android:id="@+id/stub"
        android:inflatedId="@+id/titlebar_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/titlebar"
    />
    

    在代码中:需要注意的点就是上面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性能优化(笔记)

          本文链接:https://www.haomeiwen.com/subject/rvusdttx.html