Android APP启动速度性能优化

1。统计启动耗时分布的方法

1.1 通过log统计函数运行耗时

      在需要检测的代码的前后调用System.currentTimeMillis();获取时间
然后通过log输出时间。
     通过这种方式,可以定位到哪个函数,甚至是哪句语句执行得慢。

1.2 通过log打印一个activity从启动到第一次显示的时间

      使用命令:adb logcat |grep “Displayed” ,查看activity显示需要的时间。
      会输出类似如下log:
I/ams  (  384): TID:508 .../ActivityRecord.cpp:1063:    Displayed activity dtvapp/.ILoveTVPage: 7734 ms (total 7734 ms)

     使用命令 am start -W apkName , 可以查看APP第一次启动时所需耗时。
 
1.3 使用android工具 Hierarchy Viewer进行UI性能检测

     可以参考网上资料:http://hb.qq.com/a/20110809/000032.htm
注意,三个有颜色的圆圈(取色范围为红、黄、绿色),分别代表measure 、layout、draw的速度,并且也可以看到实际运行的耗时。如果发现某个View上的圈是红色,那么说明这个View相对其他的View来说,该操作运行最慢,注意只是相对别的View,并不是说就一定很慢。红色的指示能给我们一个判断的依据,具体慢不慢还是需要自己去判断的。

2. 可能影响启动速度的地方

    (1) 在Acitivity的onCreate,onStart,onResume函数中执行过于耗时的操作。
    (2) UI用到的layout嵌套布局过多;自定义控件或UI部件实现得不好。
    (3) 启动时同时加载大量资源,包括图片,字库等。
    (4) 代码质量。

3. 优化策略

3.1 优化onCreate, onStart,onResume函数

     (1) 由于许多内容在activity的UI初始化和生命周期中需要用到,所以大部分activity中的成员需要在onCreate中通过new的方式赋值。这就要求new的类的构造函数应该尽可能简单,不要有耗时操作,以便快速执行。
     (2) 不要在这些函数中new暂时用不到的内容,比如一些提醒的dialog,可以在需要提醒的地方再去创建。

3.2优化布局文件

    (1) 减少UI的布局嵌套层数,从而减少layout时间。 简化XML布局,界面布局时,层次越多,加载的时间就越长。因此应该尽可能的减少布局层次。如果实在层次太多并且无法简化,建议不使用XML布局,直接在代码中进行布局
          判断嵌套布局是否可以优化的方法:
              i. 借助工具Hierarchy Viewer,可以看到layout比较耗时的节点。
              ii. 直接review xml布局文件。
    (2) 尽量使用RelativeLayout替换LinearLayout。
    (3) 尽量为所有分辨率创建资源,减少不必要的硬件缩放,这会降低UI的绘制速度。
    (4) 首次不需要显示的节点,尽量设置为GONE。
           
3.3 优化draw过程

    (1) 去掉不必要的背景,比如如果子节点和父节点size一样,那么父节点的background可以不设或者设为null.
    (2) 尽可能少用或者不用高质量图片,以提高运行效率。

3.4 优化数据访问

     有些属性需要在onCreate就获取,而这些属性保存在ContentProvider中。可以从下面两方面进行优化:
     (1) 少用cursor.getColumnIndex。可以在建表的时候用static变量记住某列的index,直接调用相应index而不是每次查询。
     (2) 查询时返回更少的结果集及更少的字段。只返回需要的字段和结果集,更多的结果集和字段会消耗更多的时间及内存。

3.5 优化自定义控件或UI部件

    自定义控件和UI部件,不管这些控件是否支持xml化,实现它们的代码质量很重要,要尽可能简化它们的构造过程。

3.6 代码方面的优化

    (1) 使用缓存。尽量将需要频繁访问或访问一次消耗较大的数据存储在缓存中。
    (2) 使用多线程。比较耗时的过程,尽可能的使用异步加载。避免UI主线程阻塞,发生长时间不响应。
    (3) 只需要获取图片的高宽时,可以设置InJustDecodeBounds为true。这样就不会去decode图片,减少了图片解析的时间。
    (4) 判断语句如果较多时,尽量使用switch..case..,而不是使用if..else..。因为if..else..是从上到下进行判断,而switch..case..有对判断条件进行优化。
    (5) for()循环中有if()判断,考虑实现为将if()判断语句放在for()语句外面,减少判断次数,for语句可以快速执行。
    (6) String的拼接尽量使用io流。
    (7) 数据类型和数据结构的选择。比如:hash系列数据结构查询速度更优,ArrayList存储有序元素。

3.7 其它

    通过使用Show GPU Overdraw去检测Overdraw,最终可以通过移除不必要的背景以及使用canvas.clipRect(重复绘制覆盖区域)解决大多数问题。(因为项目环境不支持这个工具,这种方法没实践过。)

posted on 2016-01-12 16:37  Jackwen  阅读(1160)  评论(0编辑  收藏  举报