Android冷启动

Android冷启动时间,从点击应用图标开始,到进入应用后屏幕绘制出第一帧为止。 本文的主要阐述内容为:

  • 分析冷启动时间
  • 优化冷启动时间

常见的分析方法

  • 通过Log分析
  • 查看Display时间
  • 通过Systrace分析,最接近真实启动时间

Systrace使用方法

进入{sdk-path}/platform-tools/systrace目录,执行以下命令,不需要的模块可以删除

python systrace.py gfx input view wm am audio video camera hal res dalvik sched freq idle disk load sync workq -b 50480 -t 5 -o trace.html

注意:抓起Systrace时,最好先执行命令,等待1~2秒后,再点击应用图标。

分析trace

在Chrome浏览器的地址栏输入:chrome://tracing/,点击load或者将trace文件拖入。

  • 左边竖栏代表进程,重点关注system_server和目标应用进程(包名)
  • 右边是时间轴
  • 可以通过W、S、A、D键,上下左右键,进行缩放或者平移。

应用级别添加Trace分析

Trace.beginSection("Module begin");
// Module code      
Trace.endSection();

注意:

  • 开始和结束必须在同一个线程,可以与其他的Trace交叉,但是必须与调用次数匹配。
  • 执行命令时,你必须通过-a或者-app=来显式地指定应用包名

分析冷启动时间

开始信号

进入左边的system_server,查找iq或者InputReader,手机会读到多个触摸事件,以第一个值为准,这里为885ms,这个值是绝对时间,不是时间区间。

应用进程启动

应用启动流程,创建进程->执行主函数ActivityTreadMain->调用BindApplication,只有冷启动才有BindApplication。

分析Trace文件,进入目标应用进程,查看UI Thread。

  • 从开始信号到ActivityTreadMain【浅绿色】时间为1038 - 885 = 153ms
  • BindApplication【紫色】的时间为1064 - 1038 = 26ms

主Activity启动

从BindApplication的结束点,到Choreographer#DoFrame(编舞者)画出第一帧的结束(finish draw)。
编舞者的第一帧只做measure和layout,第二帧才执行draw操,第二帧最后的finish draw就是结束标识。
主Activity启动的时间 = 1266 - 1064 = 202ms 时间分布如下

  • 界面绘制,包括inflate、measure、layout、draw,其中inflate时间最长,占用了很长时间。
  • 页面的业务逻辑,时间占用很小

重点分析:每个View的inflate时间

过场动画

沿着finish draw向下滑动,找到system_server->android.display,向右滑动,最后一个出现 win animation done的地方,就是动画结束的时间点。
过长动画时间:1384 - 1266 = 118ms

冷启动时间

  • 开始时间885ms,结束时间1384ms,总时间:499ms
  • 事件响应和创建进程时间:153ms
  • Application和Activity启动时间:228ms
  • 过场动画时间:118ms
  • 总结:只有Application和Activity启动时间可以优化,其他时间由系统决定。

优化冷启动时间

优化原则

  • 减少耗时操作
  • 减少View的绘制的时间

较少耗时操作

  • 初始化,Application和Activity主线程尽量不出现耗时操作,尽量放到子线程。
  • 懒加载,原则是某个类用到时,再去实例化并初始化,常见的是单例类。

Glide的懒加载

通过实现GlideModule,进行懒加载

public class GlideModuleImpl implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder glideBuilder) {
        glideBuilder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
        glideBuilder.setDiskCache(new DiskCache.Factory() {
            @Override
            public DiskCache build() {
                // TODO
            }
        });
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        glide.setMemoryCategory(MemoryCategory.NORMAL);
        ViewTarget.setTagId(R.id.glide_request);
    }

减少View的绘制时间

  • 空白页采用ViewStub方式加载,可以减少10ms+的inflate时间
  • 布局尽量采用FrameLayout方式

拓展

FSW

在启动某个应用时(点击桌机应用图标),系统(wms)为了快速响应此action, 会先根据目的activity的主题构造出一个窗口,而这个窗口通常只显示了actionBar, 背景色,这个就是传说中的starting window。因为此窗口和目的窗口在视图内容上有很大区别,所以让用户感觉到应用启动很慢。

为了尽可能的消除这个视觉落差,我们在原生的思想上,对starting window做了扩展,我们暂时叫它FSW(Fake starting window)

使用FSW后,从用户角度来看,减少冷启动时间。

results matching ""

    No results matching ""