美文网首页Android开发经验谈
Android中怎么计算apk的启动时间

Android中怎么计算apk的启动时间

作者: 左手木亽 | 来源:发表于2017-07-21 14:36 被阅读239次

    本文来自 https://www.zhihu.com/question/35487841

    这是一篇讨论怎么计算apk的启动时间...

    ActivityManager: Displayed com.android.settings/.Settings: +981ms
    

    突然好奇这个时间是怎么打印出来的、经过一段Google之后找到了上面知乎的讨论才恍然大悟,故记之...

    我补充下“adb shell am start -W ”这条命令得出的三个时间是如何计算出来的,了解了这个也就清楚了究竟哪个时间更准了。

    这里写图片描述

    “adb shell am start -W ”的实现在frameworks\base\cmds\am\src\com\android\commands\am\Am.java文件中。其实就是跨Binder调用ActivityManagerService.startActivityAndWait()接口(后面将ActivityManagerService简称为AMS),这个接口返回的结果包含上面打印的ThisTime、TotalTime时间。

    WaitTime = endTime - startTime
    

    startTime记录的刚准备调用startActivityAndWait()的时间点,endTime记录的是startActivityAndWait()函数调用返回的时间点,WaitTime = startActivityAndWait()调用耗时。

    ThisTime、TotalTime的计算在frameworks\base\services\core\java\com\android\server\am\ActivityRecord.java文件的reportLaunchTimeLocked()函数中。

    这里写图片描述

    我们来解释下代码里curTime、displayStartTime、mLaunchStartTime三个时间变量。

    curTime表示该函数调用的时间点.   
    displayStartTime表示一连串启动Activity中的最后一个Activity的启动时间点.               
    mLaunchStartTime表示一连串启动Activity中第一个Activity的启动时间点.
    

    正常情况下点击桌面图标只启动一个有界面的Activity,此时displayStartTime与mLaunchStartTime便指向同一时间点,此时ThisTime=TotalTime。另一种情况是点击桌面图标应用会先启动一个无界面的Activity做逻辑处理,接着又启动一个有界面的Activity,在这种启动一连串Activity的情况下(知乎的启动就是属于这种情况),displayStartTime便指向最后一个Activity的开始启动时间点,mLaunchStartTime指向第一个无界面Activity的开始启动时间点,此时ThisTime!=TotalTime。这两种情况如下图:

    这里写图片描述

    在上面的图中,我用①②③分别标注了三个时间段,在这三个时间段内分别干了什么事呢?

    在第①个时间段内,AMS创建ActivityRecord记录块和选择合理的Task、将当前Resume的Activity进行pause;

    在第②个时间段内,启动进程、调用无界面Activity的onCreate()等、pause/finish无界面的Activity;

    在第③个时间段内,调用有界面Activity的onCreate、onResume;

    看到这里应该清楚 ThisTime、TotalTime、WaitTime三个时间的关系了吧。WaitTime就是总的耗时,包括前一个应用Activity pause的时间和新应用启动的时间;ThisTime表示一连串启动Activity的最后一个Activity的启动耗时;TotalTime表示新应用启动的耗时,包括新进程的启动和Activity的启动,但不包括前一个应用Activity pause的耗时。也就是说,开发者一般只要关心TotalTime即可,这个时间才是自己应用真正启动的耗时。

    Event log中TAG=am_activity_launch_time中的两个值分表表示ThisTime、TotalTime,跟通过“adb shell am start -W ”得到的值是一致的。

    最后再说下系统根据什么来判断应用启动结束。我们知道应用启动包括进程启动、走Activity生命周期onCreate/onResume等。在第一次onResume时添加窗口到WMS中,然后measure/layout/draw,窗口绘制完成后通知WMS,WMS在合适的时机控制界面开始显示(夹杂了界面切换动画逻辑)。记住是窗口界面显示出来后,WMS才调用reportLaunchTimeLocked()通知AMS Activity启动完成。

    最后总结一下,如果只关心某个应用自身启动耗时,参考TotalTime;如果关心系统启动应用耗时,参考WaitTime;如果关心应用有界面Activity启动耗时,参考ThisTime。

    作者:Groffa
    链接:https://www.zhihu.com/question/35487841/answer/63007551
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

        本文标题: Android中怎么计算apk的启动时间

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