一、什么是启动时长?

1、启动时长一般包括三种场景,分别是:新装包的首次启动时长,冷启动时长、热启动时长

冷启动 和 热启动 :

(1)冷启动:当启动应用时,后台没有该程序的进程,此时启动的话系统会分配一个新的进程给应用。

(2)热启动:程序的进程依然存在,启动时通过已有进程启动进入到Activity显示页面的,就是热启动,或者从Android官网来看我们获取到的其实是温启动时长,就是Activity不存在的情况。

(3)新装包的启动时长:

新装包的启动时长,预估是最长的,并且在5.0以下及5.0以上的Android系统上的表现不同,因为:Android 5.0和更高版本使用名为ART的运行时,它原生支持从APK文件加载多个DEX文件。在应用安装时,它会执行预编译,扫描classes(..N).dex文件然后将其编译成单个.oat文件用于执行。而Android5.0以下的系统不支持,只能在程序点击启动之后,进行多个dex文件的加载,如果是在Android5.0以下的机型上获取时长,就能明显看到新装包启动时长要比其他启动时长都要长。

其中冷启动的过程如下图所示:

系统开始启动Activity的时间,就是从start u0这个时间看的,准备启动这个Activity的时间,就是这条日志前面打印出来的这个时间:

12-14 16:45:51.483 I/ActivityManager( 1370): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.ganji.android/.control.LaunchActivity bnds=[571,684][763,876] (has extras)} from uid 10021 on display 0

之后该Activity的第一帧展示出来的时候,会打印出Display的日志信息,如:

12-14 16:45:52.023 I/ActivityManager( 1370): Displayed com.ganji.android/.control.LaunchActivity: +521ms

从start u0到display第一帧的这个时间 包括了从启动进程到第一次布局与绘制的所有时间。这基本上是你需要知道的主要时间。它不包含用户点击app图标然后系统开始准备启动activity的时间,这是ok的

2、关于我们想要获取的三种场景的启动时长

(1)三种场景是启动的三种典型场景,这三种场景并没有包含将缓存和数据清除掉的情况;其中用户经历次数最多的是 “冷启动时长” 和“ 热启动时长”

(2)新装包的首次启动时长,一般情况下是最多的,在Android5.0以下系统上从APK文件加载多个dex文件的过程也包含在内。

冷启动时长居第二位,因为杀进程之后内存中的缓存会丢失,很多数据需要重新请求,并且需要重新启动进程;

热启动时长是最短的。

(3)我们想要获取启动时长的场景:

都是从初始的LaunchActivity页面进入到下一个的可操作的页面的时间;

比如以赶集网为例,新装包首次启动之后会跳转到选择城市的页面,我们需要获取的时长就是从 LaunchActivity的页面进入到SelectcityActivity的页面

因为用户一般会用到的场景是:选择城市进入到主页面,下次再启动都是直接进入到主页面,所以编写了uiautomator的脚本,能够通过UItest的方式选择城市;之后再分别获取 “冷启动时长” 和 “热启动时长”,即杀进程和正常退出程序的启动时长

二、如何获取?

1、因为通过logcat打印日志过滤ActivityManager的方式来获取启动时间,能够对其他APP也适用,因此最终确定用这种方式。

其中以赶集生活为例,新装包首次启动时长的获取,需要获取的是:从LaunchActivity的启动,到Displayed出来SelectCityActivity,刚开始用的是Displayed的后面的这个time的时长,但是跟开发确认之后,他说这个时间比用户的实际感知过程的时间还少一些,最终确定的是:

获取从start u0 LaunchActivity的时间到Display可操作的Activity的时间,拿到前面的时间节点之后,然后进行计算

以赶集网为例,三种场景下在 小米 4 + Android4.4.4的机型下,通过logcat抓到的日志如下:

新装包首次启动从Launch界面进入到选择城市的界面:

12-12 17:08:51.101 I/ActivityManager( 1191): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.ganji.android/.control.LaunchActivity} from pid 5656

12-12 17:08:58.141 I/ActivityManager( 1191): Displayed com.ganji.android/.control.LaunchActivity: +6s803ms

12-12 17:08:59.041 I/ActivityManager( 1191): START u0 {flg=0x200000 cmp=com.ganji.android/.control.BetterCityActivity (has extras)} from pid 5668

12-12 17:08:59.711 I/ActivityManager( 1191): Displayed com.ganji.android/.control.BetterCityActivity: +654ms

热启动时长:

12-12 17:11:23.571 I/ActivityManager( 1191): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.ganji.android/.control.LaunchActivity} from pid 6369

12-12 17:11:24.021 I/ActivityManager( 1191): Displayed com.ganji.android/.control.LaunchActivity: +264ms

12-12 17:11:25.311 I/ActivityManager( 1191): START u0 {cmp=com.ganji.android/.control.MainActivity} from pid 5668

12-12 17:11:27.311 I/ActivityManager( 1191): Displayed com.ganji.android/.control.MainActivity: +1s989ms

冷启动时长:

12-12 17:13:16.981 I/ActivityManager( 1191): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.ganji.android/.control.LaunchActivity} from pid 6625

12-12 17:13:18.231 I/ActivityManager( 1191): Displayed com.ganji.android/.control.LaunchActivity: +1s237ms

12-12 17:13:19.231 I/ActivityManager( 1191): START u0 {cmp=com.ganji.android/.control.MainActivity} from pid 6637

12-12 17:13:22.811 I/ActivityManager( 1191): Displayed com.ganji.android/.control.MainActivity: +3s556ms

三种场景下,都需要从start u0 cmp = LaunchActivity的时间开始,到Displayed 下一个Activity的时间结束

2、当然,也可以通过录屏的方式,录屏的命令是:

adb shell screenrecord --bugreport /sdcard/launch.mp4

之后按Ctrl+C结束,然后将视频文件导出,之后使用可按帧播放的播放器即可。

使用播放器播放的时候,可以从用户点击屏幕发白发亮的那一刻算是开始时间,这个时间可以精确到ms,之后结束的话,就以你到达的页面,并且可以等待异步加载的都完成为止。

这个与 1 中的方法相比,获取的时间是会更长一些,因为包含了点击之后有了用户的touch操作,之后 系统响应,再到系统开始响应启动进程,创建Activity,加载视图,度量并进行Activity的整体显示的过程

并且通过logcat的方式,只能用在Activity从A跳转到B的这种情况,如果是Activity不变化,只是页面数据在刷新,logcat就无法通过ActivityManager打印出日志。

最终方案确定:

最终根据我们与开发的沟通,及通过这两种方式的对比,也为了后续能够方便通过程序写成自动化的形式,选择了第一种,并且增加了通过uiautomator完成城市选择和点击back键正常退出app的UI自动化的case来支持自动化实现。

三、最后确定的方案,方案的实施和工具实现

针对以上需求:

1、方便获取竞品的对比数据,需要在同一机型上执行,并且最好执行多次,选择一个平均值

2、方便方案的通用性,以及自动化实现

通过程序实现,主要包含以下过程:

1、自动装包

2、启动logcat,清除logcat的缓存,执行 adb  logcat -v time -s ActivityManager ,并将输出内容输出到某个文件

3、启动应用程序,通过adb shell am start LaunchActivity的方式,获取新装包的启动时间;之后通过uiautomator执行UI操作,完成热启动时间的获取,之后通过adb shell am force-stop pkg包名的方式杀进程,再启动完成冷启动时间的获取

3、将日志文件从手机中pull出来

4、对日志文件进行分析,因为前面都增加了-v time 的选项,log中能够打印出具体到ms的时间,可以根据你设置的规则,直接获取某条日志前面的时间

5、获取到开始时间和结束时间之后,用结束时间减去开始时间即可

备注:

参考资料————————————

APP的安装流程:

http://www.cnblogs.com/sunshine-anycall/p/3544345.html

Android APP的启动过程:

http://blog.csdn.net/freshui/article/details/8695463

http://www.androidchina.net/3851.html

http://mp.weixin.qq.com/s?__biz=MzA4MzEwOTkyMQ==&mid=2667376274&idx=1&sn=b35396dc9e2749da076b94979c9c5424&chksm=84f33fdcb384b6cac52b98a29cf379178afe69d6761e92b4b7ad35627c722ac3dbf6887a28c7&mpshare=1&scene=1&srcid=1011ObiSQI9cClmRpq89H8XD#rd

APK预编译提取Odex:http://blog.csdn.net/huangyabin001/article/details/46973625

Android MultiDex实践:https://gold.xitu.io/entry/5705b2712e958a0057a5f735

Android应用打破65K方法数限制:http://www.infoq.com/cn/news/2014/11/android-multidex

Android developer的官网针对Launch-Time Performance的内容如下:https://developer.android.com/topic/performance/launch-time.html

http://blog.csdn.net/huangyabin001/article/details/46973625

【Android端 APP 启动时长获取】启动时长获取方案及具体实施的更多相关文章

  1. 【Android端 APP GPU过度绘制】GPU过度绘制及优化

    一.Android端的卡顿 Android端APP在具体使用的过程中容易出现卡顿的情况,比如查看页面时出现一顿一顿的感受,切换tab之后响应很慢,或者具体滑动操作的时候也很慢. 二.卡顿的原因 卡顿的 ...

  2. 【Android端 APP 内存分析】使用工具进行APP的内存分析

    Android端可以通过adb 命令直接获取内存信息,当然Android studio也提供了对内存的监控分析工具,并且后续可以结合MAT做分析 今天介绍的是通过Android studio和MAT工 ...

  3. 【Android端APP 安装包检查】安装包检查具体内容及实现方法

    一.安装包检查的具体包含内容有哪些? 1.安装包检查的一般内容包括: 安装包基本信息检查: 文件大小: xx MB 包名: com.xx 名称:  xx 本次安装包证书与外网证书对比一致性:是 版本号 ...

  4. C#服务端通过Socket推送数据到Android端App中

    需求: 描述:实时在客户端上获取到哪些款需要补货. 要求: 后台需要使用c#,并且哪些需要补货的逻辑写在公司框架内,客户端采用PDA(即Android客户端 版本4.4) . 用户打开了补货通知页面时 ...

  5. Appium自动化时,如何快速获得Android app的包名和启动页

    在app自动化的时候,经常被问道如何知道app的包名和启动页名称.这个问题很简单: 1. 最直接的方式,去问开发啊,他们告诉你app的包名和启动页. 2. 如果你比较腼腆,又能看到/懂代码,自己把代码 ...

  6. Android Launcher分析和修改9——Launcher启动APP流程

    本来想分析AppsCustomizePagedView类,不过今天突然接到一个临时任务.客户反馈说机器界面的图标很难点击启动程序,经常点击了没有反应,Boss说要优先解决这问题.没办法,只能看看是怎么 ...

  7. Android手机app启动的时候第一个Activity必须是MainActivity吗

    原文:Android手机app启动的时候第一个Activity必须是MainActivity吗 Android手机APP启动的第一个Activity是可以自己设置的,不是必须的MainActivity ...

  8. Android在应用中依据包名启动另外一个APP

    以下为TestIntentData工程 MainActivity如下: package cn.testintentdata; import java.util.List; import android ...

  9. Android性能优化(一)之启动加速35%

    一.前言 随着项目版本的迭代,App的性能问题会逐渐暴露出来,而好的用户体验与性能表现紧密相关,从本篇文章开始,我将开启一个Android应用性能优化的专题,从理论到实战,从入门到深挖,手把手将性能优 ...

随机推荐

  1. Oracle分区表!

    Oracle 数据库分区表的创建和操作 摘要:在大量业务数据处理的项目中,可以考虑使用分区表来提高应用系统的性能并方便数据管理,本文详细介绍了分区表的使用. 在大型的企业应用或企业级的数据库应用中,要 ...

  2. 常用的.Net 知识点

    1.Replace C#:(using System.Text.RegularExpressions;) string txt = Regex.Replace(txtLog.Text.ToString ...

  3. 数据库使用--MyISAM InnoDB 区别

    MyISAM 和 InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处 ...

  4. 安装完Pydev却无法创建Python工程

    为了方便以后工作,今天在ADT里面安装了Pydev(http://pydev.org/updates),可是安装完之后,新建项目的时候却找不到Pydev,perference中也没有. 紧接着尝试安装 ...

  5. ACM知识点

    基础算法 高精 模拟 分治 贪心 排序 DFS 迭代加深搜索 BFS 双向BFS 动态规划 DAG上DP 树上DP 线性DP 图算法 最短路 FLYD DJATL BF 最大流 Dinic ISAP ...

  6. 《JavaScript高级程序设计》学习笔记(2)--JS运算符详解

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 思维导图 前面对JS的运算符的操作很多细节的东西没有提及,今天给大家分享一张网上找的思维导图,对这一部 ...

  7. php使用ajax导出CSV或者EXCEl(thinkphp)方法

    首先我强烈推荐看到这篇文章的你将导出文件设置为csv格式的文件 实际测试导出csv文件的速度是excel文件的10几倍左右 首先我先介绍csv文件的导出的方法: 如果你单纯是在数据导出界面上通过用户点 ...

  8. 低版本的xcode打开xcode8上的xib错误

    XIB和Storeboard适配 在Xcode8之前,创建一个XIB或SB文件,都是一个600*600的方块XIB文件.在Xcode8之后,创建的XIB文件默认是6s尺寸的大小. 但是Xcode8打开 ...

  9. php创建文件并写入信息

    $myfile = fopen("c:\\newfile.txt", "w") or die("Unable to open file!") ...

  10. Zepto 使用过程中遇到的问题总结

    简言之,zepto 是移动端的 jQuery,虽然很多地方不完全相同,不过详细的内容就不介绍了,主要把使用 zepto 时遇到过的问题总结一下. zepto 是分成多个模块的,最基础的文件不包含 to ...