Android开发艺术探索 第15章 Android性能优化 读

作者: HuDP | 来源:发表于2016-06-13 16:42 被阅读2466次

    正式开始前,推荐一下Android开发艺术探索的其他笔记 Android开发艺术探索 读书笔记目录
    下面正文开始。


    Android设备作为一种移动设备,不管是内存还是CPU的性能都受到了一定的限制,也意味着Android程序不可能无限制的使用内存和CPU资源,过多的使用内存容易导致OOM,过多的使用CPU资源容易导致手机变得卡顿甚至无响应(ANR)。这也对开发人员提出了更高的要求。
    本章主要介绍一些有效的性能优化方法。主要包括布局优化、绘制优化、内存泄漏优化、响应速度优化、ListView优化、Bitmap优化、线程优化等;同时还介绍了ANR日志的分析方法。


    15.1 Android的性能优化方法

    Google官方的Android性能优化典范专题短视频课程是学习Android性能优化极佳的课程,目前已更新到第五季;
    放一个Google官方维护的国内方便访问的链接地址 youku地址

    15.1.1 布局优化
    1. 布局优化的思想就是尽量减少布局文件的层级,这样绘制界面时工作量就少了,那么程序的性能自然就高了。
      删除无用的控件和层级,其次就是有选择的使用性能较低的ViewGroup,如果布局中既可以使用Linearlayout也可以使用RelativeLayout,那就是用LinearLayout,因为RelativeLayout功能比较复杂,它的布局过程需要花费更多的CPU时间。有时候通过LinearLayou无法实现产品效果,需要通过嵌套来完成,这种情况还是推荐使用RelativeLayout,因为ViewGroup的嵌套相当于增加了布局的层级,同样降低程序性能。

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

      • <include>标签
        <include>标签用于布局重用,可以将一个指定的布局文件加载到当前布局文件中。<include>只支持android:layout_开头的属性,当然android:id这个属性是个特例;如果指定了android:layout_这种属性,那么要求android:layout_width和android:layout_height必须存在,否则android:layout_属性无法生效。如果<include>指定了id属性,同时被包含的布局文件的根元素也指定了id属性,会以<include>指定的这个id属性为准。
    • <merge>标签
      <merge>标签一般和<include>标签一起使用从而减少布局的层级。如果当前布局是一个竖直方向的LinearLayout,这个时候被包含的布局文件也采用竖直的LinearLayout,那么显然被包含的布局文件中的这个LinearLayout是多余的,通过<merge>标签就可以去掉多余的那一层LinearLayout。

    • ViewStub
      ViewStub意义在于按需加载所需的布局文件,因为实际开发中,有很多布局文件在正常情况下是不会现实的,比如网络异常的界面,这个时候就没必要在整个界面初始化的时候将其加载进来,在需要使用的时候再加载会更好。在需要加载ViewStub布局时:

    ((ViewStub)findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
    //或者
    View importPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate();
    

    当ViewStub通过setVisibility或者inflate方法加载后,ViewStub就会被它内部的布局替换掉,ViewStub也就不再是整个布局结构的一部分了。

    15.1.2 绘制优化

    View的onDraw方法要避免执行大量的操作;

    1. onDraw中不要创建大量的局部对象,因为onDraw方法会被频繁调用,这样就会在一瞬间产生大量的临时对象,不仅会占用过多内存还会导致系统频繁GC,降低程序执行效率。
    2. onDraw也不要做耗时的任务,也不能执行成千上万的循环操作,尽管每次循环都很轻量级,但大量循环依然十分抢占CPU的时间片,这会造成View的绘制过程不流畅。根据Google官方给出的标准,View绘制保持在60fps是最佳的,这也就要求每帧的绘制时间不超过16ms(1000/60);所以要尽量降低onDraw方法的复杂度。
    15.1.3 内存泄露优化

    内存泄露是最容易犯的错误之一,内存泄露优化主要分两个方面;
    一方面是开发过程中避免写出有内存泄露的代码,另一方面是通过一些分析工具如LeakCanary或MAT来找出潜在的内存泄露继而解决。

    1. 静态变量导致的内存泄露
      比如Activity内,一静态Conext引用了当前Activity,所以当前Activity无法释放。或者一静态变量,内部持有了当前Activity,Activity在需要释放的时候依然无法释放。
    2. 单例模式导致的内存泄露
      比如单例模式持有了Activity,而且也没用解注册的操作。因为单例模式的生命周期和Application保存一致,生命周期比Activity要长,这样一来就导致Activity对象无法及时被释放。
    3. 属性动画导致的内存泄露
      属性动画中有一类无限循环的动画,如果在Activity播放了此类动画并且没有在onDestroy中去停止动画,那么动画会一直播放下去,并且这个时候Activity的View会被动画持有,而View又持有了Activity,最终导致Activity无法释放。解决办法是在Activity的onDrstroy中调用animator.cancel()来停止动画。
    15.1.4 响应速度优化和ANR日志分析

    响应速度优化的核心思想就是避免在主线程中去做耗时操作,将耗时操作放在其他线程当中去执行。Activity如果5秒无法响应屏幕触摸事件或者键盘输入事件就会触发ANR,而BroadcastReceiver如果10秒还未执行完操作也会出现ANR。
    当一个进程发生ANR以后系统会在/data/anr的目录下创建一个文件traces.txt,通过分析该文件就能定位出ANR的原因。

    15.1.5 ListView优化和Bitmap优化

    ListView/GridView优化:采用ViewHolder避免在getView中执行耗时操作;其次通过列表的滑动状态来控制任务的执行频率,比如快速滑动时不是和开启大量异步任务;最后可以尝试开启硬件加速使得ListView的滑动更加流畅。
    Bitmap优化:主要是想是根据需要对图片进行采样显示,详细请参考12章。

    15.1.6 线程优化

    线程优化的思想是采用线程池,避免程序存在大量的Thread。详细参考第11章的内容。

    15.1.7 一些性能优化的小建议
    • 避免创建过多的对象,尤其在循环、onDraw这类方法中,谨慎创建对象;
    • 不要过多的使用枚举,枚举占用的内存空间比整形大。
    • 常量使用static final来修饰;
    • 使用一些Android特有的数据结构,比如SparseArray和Pair等,他们都具有更好的性能;
    • 适当的使用软引用和弱引用;
    • 采用内存缓存和磁盘缓存;
    • 尽量采用静态内部类,这样可以避免非静态内部类隐式持有外部类所导致的内存泄露问题。

    15.3 提高程序的可维护性
    1. 提高可读性:命名规范;代码之间排版需留出合理的空白来区分不同的代码块;针对非常关键的代码添加注释。
    2. 代码的层级性:不要把一段业务逻辑放在一个方法或者一个类中全部实现,要把它分成几个子逻辑,然后每个子逻辑做自己的事情,这样即显得代码层级分明,这样利于提高程序的可扩展性。
    3. 恰当的使用设计模式可以提高代码的可维护性和可扩展性,Android程序容易遇到性能瓶颈,要控制设计的度,不能太牵强,避免过度设计。作者推荐查看《大话设计模式》和《Android源码设计模式解析和实战》这两本书来学习设计模式。

    相关文章

      网友评论

      • 姬94:这本书写的真的很棒 很难找到超过他的分析书了 有其他好书推荐吗
        姬94:@HuDP 我有看,android源码设计模式,我感觉写的不太好,看不下去的感觉,从设计模式的角度,他花了大量篇幅分析辅助材料,以偏概全了。而且,我感觉,书上没有抽出设计模式精华,有点堆代码的嫌疑,有些代码偏离了。他内容的主线,我看的不知所云。然后突然间又回来了。我个人感觉,有点水。看两遍都停留在第六章,真心看不再去。
        HuDP:@姬94 Android源码设计模式
      • LeoYe168:我怎么记得是尽量选用相对布局,而不用线性布局的,因为前者性能更好。。mark下
        HuDP:@LeoYe168 如果相对布局可以减少层级了 那就用相对布局性能更优呢
      • 琴声悠扬TODO:都看到15章了,第一章没看完,,
        HuDP:@恨自己不能小清新 哈哈 我买回来两个月的时候 也是哥们你这样:joy::joy::joy:
        恨自己不能小清新:@琴声悠扬TODO 我特么买回来两个月了 都没翻开过 草草草 :smile:
        HuDP:@琴声悠扬TODO 啊哈 慢慢看过来呗,一步一个脚印

      本文标题:Android开发艺术探索 第15章 Android性能优化 读

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