怎么计算apk的启动时间?

利用python或者直接用adb命令怎么计算apk的启动时间呢?就是计算从点击图标到apk完全启动所花费的时间。比如,对游戏来说就是点击游戏图标到进入到登录界面的这段时间。
已知的两种方法貌似可以获取,但是感觉结果不准确:一种是,adb shell am start -w packagename/activity,这个可以得到两个值,ThisTime和TotalTime,不知道两个有什么区别,而且与实际启动时间不匹配,两者相加都可能比实际启动时间小(测试游戏的时候差别更大);另外一种是通过adb logcat的方式,感觉获取的结果也与实际有差别。

启发,Android framework

终于有空来填坑啦。关于应用启动速度,@Gracker已经回答的很完善了。我补充下“adb shell am start -W ”这条命令得出的三个时间是如何计算出来的,了解了这个也就清楚了究竟哪个时间更准了。
怎么
“adb shell am start -W ”的实现在frameworksbasecmdsamsrccomandroidcommandsamAm.java文件中。其实就是跨Binder调用ActivityManagerService.startActivityAndWait()接口(后面将ActivityManagerService简称为AMS),这个接口返回的结果包含上面打印的ThisTime、TotalTime时间。

启动

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

ThisTime、TotalTime的计算在frameworksbaseservicescorejavacomandroidserveramActivityRecord.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

monkey code,酱油

题主所说的thistime或者logcat中 eventslog的lauchtime都是从startActivity开始算起,你也发现了实际的时间和这个有差距,差距的时间大部分就是Launch处理OnClick。
相对精确的时间从代码上想看到,可以在InputDispatch中留桩记录时间和Wms显示Displayed的时间相减,就差不多等于实际的时间。(这个差距取决于tp事件的处理速度,一般很小)。
不过还可以提醒下题主,一般的平台代码中都会有类似touchBurst(有touch事件就开核升频)的功能,所以你am start /input 模拟点击可能还会比实际的要慢,这个可以从systrace上对比下就清楚了。
所以,如果想知道很精确的,高速相机+开发者模式打开指针位置,你就知道了。

郑超超,我虽然懒,但我还是希望能为这个世界做些…

哈哈哈哈,这个真知道。想很准确吗?高速摄像头加压力传感器啊。不然只能题主那样定性估算一下。那都是代码级别的,跟实际肯定有差距。

许辉,IT

更关心有无优化空间。安装和启动时间

mark zhai,码农一枚

对应用开发者来说,应该是从application的onCreate(或者attachBaseContext),一直到首个activity的onStart,这是可优化的时间



原网址:http://mail.cfanz.cn/index.php?c=article&a=read&id=280013

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值