① 分享:android屏幕刷新机制下页面性能统计及优化
一、Android屏幕刷指首余新机制芹拿
1、三级缓存
2、surfaceflinger surface
二、页面性能统计实现
指标
1、首次内唯滚容渲染时间(FCP)
2、首次有效渲染时间(FMP)
3、可交互时间(TTI)
4、应用冷启动时间
5、每帧处理时间
三、app应该如何去优化
② 如何检测App启动时间
对于app的性能测试,启动时间是个重要指标,启动时间分为两种情况,一种是冷启动时间(通常是系统重启,即在启动前没有该app进程的情况),另一种是热启动,即app从被切换到前台(点back退出后再点击图标启动)。
从Android4.4(API 19)开始,可以从logcat获取activity的启动信息,如下我用应用宝做实验,可以看到如下的输出,从这里我们可以看到应用的这个activity启动用了639ms。
12-13 00:10:41.331 855-957/? I/ActivityManager: [AppLaunch] Displayed Displayed com.tencent.android.qqdownloader/com.tencent.assistantv2.activity.MainActivity: +639ms (total +751ms)
12-13 00:10:41.331 855-957/? D/ActivityManager: AP_PROF:AppLaunch_LaunchTime:com.tencent.android.qqdownloader/com.tencent.assistantv2.activity.MainActivity:639:50307447
这个log信息会在activity首次被绘制时输出,也就是如果activity栈里有这个activity,再启动不会输出该信息,典型的场景是通过recent task列表切换到其他activity再立即切换回来时。
log中的时间包括系统从开始处理启动activity的时间到完成运行layout和draw函数的时间,不包括点击icon到系统接收到消息的时间。显然,这个时间也不包括启动中异步UI绘制的时间。但是我们在测试中关注的其实是用户体验的启动时间,那么上面log中的时间就不能满足我们的需求了。
不过还好,既然是用户体验我们可以用更直观的方式,使用screenrecord进行屏幕录制然后分析视频。使用如下命令录制视频。
adb shell screenrecord –bugreport /sdcard/launch.mp4
–bugreport参数会使视频输出一些时间信息和帧信息便于我们分析启动时间。activity启动后,使用ctrl+c结束视频录制,使用
adb shell pull /sdcard/launch.mp4 /Users/xxx/Downloads/launch.mp4
导出视频到电脑,使用可以按帧播放的视频软件打开(mac上quicktime就可以,win下可以用kmplayer),并按帧播放。
按帧播放视频,视频左上角会显示每一帧的时间(精确到ms)和帧数。在视频中会看到icon会变暗然后高亮,高亮时就是系统开始处理本次icon点击事件了。可以把这里作为点击时间,然后根据体验要求,看到app启动页完全绘制完作为终止时间,这个时间减去点击时间就是app的启动时间。
在进行app启动时间测试时,系统中运行的其他app会对启动时间有干扰,如果需要进行版本对比及竞品对比,最好要尽量保持环境一致,并反复执行多次取平均值。最后,不要忘了分别测试冷启动和热启动哦~
③ Android性能优化第(八)篇---App启动速度优化之耗时检测处理
应用的启动速度缓慢这是很多开发者都遇到的一个问题,比如启动缓慢导致的黑屏,白屏问题,大部分的答案都是做一个透明的主题,或者是做一个Splash界面,但是这并没有从根本上解决这个问题。那么如何从根本上解决这个问题或者做到一定程度的缓解?
1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会首先会创建一个新的进程分配给该应用,这种启动方式就是冷启动。
2、热启动:当启动应用时,后台已有该应用的进程,比如按下home键,这种在已有进程的情况下,这种启动会从已有的进程中来启动应用,这种启动方式叫热启动。
3、温启动 :当启动应用时,后台已有该应用的进程,但是启动的入口Activity被干掉了,比如按了back键,应用虽然退出了,但是该应用的进程是依然会保留在后台,这种启动方式叫温启动。
adb shell am start -W [PackageName]/[PackageName.MainActivity]
执行成功后将返回三个测量到的时间:
这里面涉及到三个时间,ThisTime、TotalTime 和 WaitTime。WaitTime 是 startActivityAndWait 这个方法的调用耗时,ThisTime 是指调用过程中最后一个 Activity 启动时间到这个 Activity 的 startActivityAndWait 调用结束。TotalTime 是指调用过程中第一个 Activity 的启动时间到最后一个 Activity 的 startActivityAndWait 结束。如果过程中只有一个 Activity ,则 TotalTime 等于 ThisTime。
总结:如果只关心某个应用自身启动耗时,参考TotalTime;如果关心系统启动应用耗时,参考WaitTime;如果关心应用有界面Activity启动耗时,参考ThisTime。
从我们Application开始到首页显示出来,这个过程,我们应该注意一些什么,将这个过程细分一下,会有下面的时间点需要注意。
Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量、布局、绘制显示在界面上。
因为上面这些阶段全部都是在主线程中执行的,任何不经意的操作都可能拖慢应用的启动速度。所以我们不应在Application以及Activity的生命周期回调中做任何费时操作,具体指标大概是你在onCreate,onResume,onStart等回调中所花费的总时间最好不要超过400ms,否则用户在桌面点击你的应用图标后,将感觉到明显的卡顿。但是有些 不得以的任务 又必须在UI显示之前执行。所以我们要将 任务 划分优先级。
对于首页渲染完成后,开始加载,或者延迟加载,延迟加载的目的就是界面先显示出来,然后加载,但是你觉得要延迟多久呢?在 Android 的高端机型上,应用的启动是非常快的 , 这时候只需要 Delay 很短的时间就可以了, 但是在低端机型上,应用的启动就没有那么快了,而且现在应用为了兼容旧的机型,往往需要 Delay 较长的时间,这样带来体验上的差异是很明显的。延迟加载有一种方式。
极力推荐用第二种,在窗口完成以后进行加载,这里面的run方法是在onResume之后运行的。关于这种懒加载机制,参考 Android应用启动优化:一种DelayLoad的实现和原理(上篇) ,给出了详细的解释。
通过上面我们知道一种懒加载机制,所以我们可以将Application中和首页的onCreate中的有些耗时任务,放到首页渲染完毕后加载。如何找出这些耗时任务,TraceView就派上用场了,TraceView的用法,移步我的前面的博客 Android性能优化第(六)篇---TraceView 分析图怎么看?
比如在首页的onCreate中我们进行了用户启动上报,这个进行懒加载是不是分分钟减少139毫秒呢?
在比如在Application里面用到了GSON,将String转化成json,我将这个移动到懒加载里面,是不是又减少了100毫秒呢?
在比如,有些Application中做了支付SDK的初始化,用户又不会一打开App就要支付,放在Application中加载干嘛?
此处我们这里举得例子是优化了139毫秒和100毫秒的,其实真正耗时的任务有的有1秒多,都被我优化完了,所以trace图中看不到了,就举个了这两个例子,还有SharedPreferences也是耗时大户,经过检测保存一个boolean变量耗时120+毫秒以上。
利用TraceView可以清楚我们每一个方法的耗时时间,极大的帮助了我们做优化工作。
五、优化思路总结
1、UI渲染优化,去除重复绘制,减少UI重复绘制时间,打开设置中的GPU过度绘制开关,各界面过度绘制不应超过2.5x;也就是打开此调试开关后,界面整体呈现浅色,特别复杂的界面,红色区域也不应该超过全屏幕的四分之一;
2、根据优先级的划分,KoMobileApplication的一些初始化工作能否将任务优先级划分成3,在首页渲染完成后进行加载,比如:PaySDKManager。
3、主线程中的所有SharedPreference能否在非UI线程中进行,SharedPreferences的apply函数需要注意,因为Commit函数会阻塞IO,这个函数虽然执行很快,但是系统会有另外一个线程来负责写操作,当apply频率高的时候,该线程就会比较占用CPU资源。类似的还有统计埋点等,在主线程埋点但异步线程提交,频率高的情况也会出现这样的问题。
4、检查BaseActivity,不恰当的操作会影响所有子Activity的启动。
5、对于首次启动的黑屏问题,对于“黑屏”是否可以设计一个.9图片替换掉,间接减少用户等待时间。
6、对于网络错误界面,友好提示界面,使用ViewStub的方式,减少UI一次性绘制的压力。
7、任务优先级为2,3的,通过下面这种方式进行懒加载的方式
8、Multidex的使用,也是拖慢启动速度的元兇,必须要做优化。后面有空专门写一篇Multidex。
相关链接:
Android应用启动优化:一种DelayLoad的实现和原理(上篇)http://androidperformance.com/2015/11/18/Android-app-lunch-optimize-delay-load.html
Android性能优化之加快应用启动速度http://www.open-open.com/lib/view/open1452821612355.html
手机淘宝性能优化全记录http://www.open-open.com/lib/view/open1452488209370.html
Android客户端性能优化(魅族资深工程师毫无保留奉献)http://blog.tingyun.com/web/article/detail/155#rd
Please accept mybest wishes for your happiness and success !
④ android APP冷启动时间过长,怎么解决
这个可不好说了,具体关闭程序是由拦销Framework决定的。 一般按照如下规律。 1、内存紧张、先关闭没有SERVICE、ACTIVITY堆栈时间最长的。 2、内存紧张、有SERVICE,不活动时间最长的。占用内存比较大的。 3、内存紧张、有大内存程序切换到前台,释放内存依旧不够的。依次杀死不活动时间最长的。 4、内存紧张、有大内存程序切换到前台丛轮,释放内存依旧不够的。杀死带有android:persistent="true"标记的。(备注Phone模块有此标记,所以最难杀) 这个简郑游是我的经验。
⑤ Android启动优化概述
Android启动应用, 按 官方说法 分为冷启动, 温启动和热启动.
具体的定义可以看官方文档, 简单地说
一般我们只需要关注冷启动即可.
要想启动快, 硬件性能必然有影响, 在硬件一定的前提下, 我们要尽量 降低启动应用时CPU的负载 , 让CPU有更多的算力投入到启动流程中:
在做好一些基本原则后, 接着看具体的流程优化点
在应用进程创建后, 首先必然是加载类, 此时一些静态变量就会初始化了, 因此我们应该
类加载完毕后就是创建 Application 实例了, 因此我们应该
之后会先创建 ContentProvider 和执行 ContentProvider.onCreate() , 因此我们应该
跟接着就会执行 Application.onCreate() 等方法, 因此我们应该
接着就进入 Activity 环节.
同样第一步会是创建实例, 因此我们应该
在 Activity 进程生命周期后, 第一步就是渲染(inflate)布局, 我们应该
在应用启动的瞬间, 系统服纳亏务会先展示一个空白窗口哪茄歼, 等待应用第一帧绘制完毕后, 再从该窗口切换到应用, 如果启动耗时较长, 就会明显看到白屏, 对于这一点, 常见的操作有
可以使用IdleHandler, 在主线程空闲时再执行某些不重要的操作
实际上异步初始化只是不阻塞主线程, 但是子线程一样会占用CPU资源, 让主线程的执行时间变少, 所以不应该盲目地将所有工作放到子线程.
优化做到最后, 就是在系统流程上做文章了
原理是将启动时加载的类放到主dex,提升了这些类的内聚,让更多的类满足pre-verify的条件,在安装时就做了校验和优化,以减少首次加载的耗时,从而优化冷启动耗时。
Redex 初探与 Interdex:Andorid 冷启动优化
应用启动过程中会从apk压缩包中读取文件, 该优化的原理是利用Linux中的Pagecache机制, 让启动过程会用到的文件尽可能进入缓存中, 减少磁盘IO次数
支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能
在Dalvik VM(Android5.0以前)加载类的时候会有一个类校验过程, 它需要校验方李冲法的每一个指令, 是一个比较耗时的过程, 可以通过Hook去掉类加载过程中的类验证过程. 不过对于ART(Android5.0之后)来说, 这个过程在安装时已经做了, 所以用处不大.
不进入冷启动, 就不用优化了~
这个Android Studio自带的工具, 可以看到启动过程中详细的方法执行流程, 但是采集数据本身会影响方法执行, 所以不能准确判断每个方法的耗时, 但是仍可以判断哪个方法相对来说耗时.
这个工具的好处是可以自定义事件, 可以指定需要采集的数据集, 可以看到线程间的状态等.
启动优化的一个关键点在于定义启动结束的点, 以及如何测量启动时间.
在Android4.4以上, 系统进程会提供一个类似 ActivityManager: Displayed ***: +3s534ms 的日志, 表示从启动进程到首次绘制完毕所用的时间.
应用可以在任何时候调用该方法, 触发系统打印类似 system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms 的日志
应用可以通过 ViewTreeObserver 来监听绘制前回调来判断第一帧的绘制时机, 或者直接在控件树的末尾加一个简单的View, 它 onDraw 调用时即表示页面(差不多)绘制完毕.
应用启动过程可以参考 Android Vitals Series' Articles 系列文章
⑥ android APP冷启动时间过长,怎么解决
找到在启动的时候做的耗时操作,该去局告掉的去掉,该延时加载的延时加载
其他几个思路,
1、Application中不要做任何业务相关的操作
2、有些耗时的操作可以桐橘明在真正使用到的时候去创建或者执行
3、添加过渡页,显得更自然些,大伍链多数App都是这么做的
4、首页的界面可以优化下,不要过度绘制
⑦ Android 5.0、6.0、7.0、8.0、9.0、10.0特性
1.扁平化,设计理念(Material Design);
2.新设计风格(Material Design材料设计,参考文档: https://materialdoc.cn/ );
3.全新的通知中心设计,优先显示对用户来说比较重要的信息,把不太紧要的隐藏起来,向下滑动就可以查看所有通知。通知功能的另一个炫酷新功能是在锁屏的时候就可以直接查看通知消息,还可以在锁屏下直接回复或进入应用。另外在操作手机的过程中有电话进入,也不会进行全画面切换,而是同样以弹出的当时告知用户;
4.开始支持多种设备(智能手机、平板电脑、笔记本电脑、智能电视、汽车等);
5.性能上放弃Dalvik虚拟机,改用ART模式,实现跨平台编译,程序加载时间大幅度提升,未来Android智能手机支持4GB以上的内存;
6.增加了Battery Saver模式进行省电处理;
7.全新的最近应用程序;
8.改进安全性,当用户的蓝牙耳机连接到手机或平板电脑时,设备可以基于当前的位置和用户的声音自动解锁,绕过锁屏界面;
9.不同数据独立保存;
10.改进搜索
11.支持蓝牙4.1、USB audio、多人分享等其他特性。
1.为用户提供了两套相互独立的解决方案,即数据存储方案(1.一套存储工作资料,2.存储个人信息);
2.Android M系统层面加入了指纹识别(厂商自行开发的改为原生的,提升了指纹支付安全性);
3.APP关联(APP links),在微信打开京东链接,会提醒跳转到京东APP;
4.Android pay,Android支付唯一标准,简洁、安全、可选性;
5..运行时权限(危险权限和正常权限);
6.电源管理,APP standby(应用待机),Doze(瞌睡),Exemptions(豁免),生命周期等模式来加强电源管理。
提升性能、生产效率和安全性,无缝更新
1.对文件数据加密,更加安全;旦闷
2.添加了分屏多任务;
3.全新下拉快捷开关页,例如WiFi的开关;
4.重新设计了通知,消息归拢,通知消息快捷回复,如视频全屏下,屏幕顶部出现两个按钮(接听、挂掉);
5.夜间模式;
6.流量保护;
7.全新设置样式;
8.改进Doze休眠机制;
9.系统级电话黑名单功能;
10.菜单键快速应用切换;
一、Fluid Experiences概念,提高生产力,日常使用中可以使用多个任务工具
1.画中画,悬浮小窗口,与分屏不相同;
2.TensorFlow Lite,谷歌将人工智能应用在应用程序中的尝试,并进一步将机器学习的优势扩展到Android生态系统;
3.Notification Dots,桌面程序未读消缺陵息小图标提示;
4.Smart Text Seletion(智能文本选择),导航应用,电话号码,邮件等应用;
5.auto-fill(自动填写),例如记住密码;
6.自适应图标(adapter icons)模扮弯;
7.固定快捷方式和小部件(pinning shortcuts),长按应用桌面图标弹出提示;
二、Vitals,新概念,对于设备电池续航、安全、应用启动时间和稳定性的优化
1.Google Play Project,Android应用的病毒扫描程序;
2.系统、应用启动程序加速,为原来系统的一半时间;
3.Play Console Dashbard,新的开发人员工具,可提供应用在设备上使用情况分析,开发人员 可以深入了解如何调整应用程序,以减少电池消耗并提高在各个设备上的运行速度;
4.其他特性:字体、WiFi感知
1.adaptive battery自适应电池,如果在Android 6中使用了休眠模式,它会让所有的程序都休眠,而自适应电池功能是它的一个进阶版,默认情况下是启用的;
2.Actions和Slices,为你的手机提供一些建议,如插入耳机会显示最近播放列表或者建议你打个电话;
3.切片,跳出执行信息对话中列出的操作;
4.shush,屏幕朝下时进入完全勿扰模式;
5,通知栏的多种通知;
6.通过WiFi rtt 进行室内导航;
7.改进dnd模式;
8.所有应用都是用HTTPS;
9.后台程序无法访问相机和麦克风;
10.wind down,夜间模式;
11.Android Dashboard,应用使用时间提醒;
12.网络还有神经网络,节省流量和网速优化;
13.多摄像头的更多画面;
14.全面屏支持。
1.可折叠设备(更改了resizeableActivity) 清单属性的工作方式);
2.5G网络,提速降延迟;
3.通知中的智能回复(提供建议和操作,并支持自定义回复和操作;使用 setAllowGeneratedReplies()和()即可精确选择停用);
4.系统级深色主题;
5.全手势导航;
6.新的设备面板;
7.共享快捷方式;
8.保护用户隐私,给予用户更多权限控制权;
9.安全性等。
⑧ 怎么计算android app启动时间
事实上 Android 中一个 App 的启动时间可以准确计算的.但是要分场景.也就是说要分开游戏和应用. 大家都知道,在Android中,游戏开发和应用开发是两码事.所以我们需要分开来说.
1.1 应用启动
我们平时在写应用的时候,一般会指定一个 mainActivity ,用户在桌面上点击这个 Activity 的时候,系统会直接起这个 Activity. 我们知道 Activity 在启动的时候会走 onCreate/onStart/onResume .这几个回调函数.
许多书里讲过,当执行完 onResume 函数之后,应用就显示出来了…其实这是一种不准确的说法,因为从系统层面来看,一个 Activity 走完 onCreate/onStart/onResume 这几个生命周期之后,只是完成了应用自身的一些配置,比如 window 的一些属性的设置/ View 树的建立(只是建立,并没有显示,也就是说只是调用了 inflate 而已) . 后面 ViewRootImpl 还会调用两次performTraversals ,初始化 Egl 以及 measure/layout/draw. 等.所以我们定义一个 Android 应用的启动时间, 肯定不能在 Activity 的回调函数上下手.而是以用户在手机屏幕上看到你在 onCreate 的 setContentView 中设置的 layout 完全显示为准,也就是我们常说的应用第一帧.
上面扯得有点远,不感兴趣的话可以不看,下面直接说方法.题主说的 adb shell am start -w packagename/activity,是可以完全应用的启动时间的.不过也要分场景.
1.2 应用第一次启动
也就是我们常说的冷启动,这时候你的应用程序的进程是没有创建的. 这也是大部分应用的使用场景.用户在桌面上点击你应用的 icon 之后,首先要创建进程,然后才启动 MainActivity.这时候adb shell am start -w packagename/MainActivity 返回的结果,就是标准的应用程序的启动时间(注意 Android 5.0 之前的手机是没有 WaitTime 这个值的):
➜ adb shell am start -W com.meizu.media.painter/com.meizu.media.painter.PainterMainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.meizu.media.painter/.PainterMainActivity }
Status: ok
Activity: com.meizu.media.painter/.PainterMainActivity
ThisTime: 355
TotalTime: 355
WaitTime: 365
Complete
总共返回了三个结果,我们以 WaitTime 为准.
关于ThisTime/TotalTime/WaitTime的区别,下面是其解释:
“adb shell am start -W ”的实现在 frameworks\base\cmds\am\src\com\android\commands\am\Am.java 文件中。其实就是跨Binder调用ActivityManagerService.startActivityAndWait() 接口(后面将ActivityManagerService简称为AMS),这个接口返回的结果包含上面打印的ThisTime、TotalTime时间.
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。
看到这里应该清楚 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。
1.2 应用非第一次启动
如果是你按Back键,并没有将应用进程杀掉的话,那么执行上述命令就会快一些,因为不用创建进程了,只需要启动一个Activity即可。这也就是我们说的应用热启动。
2 游戏启动场景
游戏启动的话,就不适用用命令行的方法来启动了,因为从用户点击桌面图标到登录界面,既有系统的部分也有游戏自己的部分。
2.1 系统部分
游戏也有一个Activity,所以启动的时候还是会去启动这个Activity,所以系统启动部分也就是用户点击桌面桌面响应到这个Activity启动。
2.2 游戏部分
一般游戏的主Activity启动后,还会做一些比较耗时的事情,这时候你看到的界面是不能操作的,比如:加载游戏数据、联网更新数据、读取和更新配置文件、游戏引擎初始化等操作。从游戏开发的角度来看,到了真正用户能操作的界面才算是一个游戏真正加载完成的时间。那么这个时间,就得使用Log来记录了,因为加载游戏数据、联网更新数据、读取和更新配置文件、游戏引擎初始化这些操作,都是游戏自己的逻辑,与系统无关,所以得由游戏自己定义加载完成的点。
对于游戏的启动时间,我们更倾向于计算从 点击桌面图标 到 用户可以与游戏进行交互 这个时间段作为一个游戏的启动时间。
3 总结
计算机最让人着迷的一点就是其准确性,1+1永远等于2,启动耗时多久就是多久,每一次可能不一样,但每一次的时间都是这一次的准确时间。
不过每个公司由于对应用的定位不同,所以对应用启动的要求也不一样。比如有的做 ROM 的公司,其内置应用的启动时间一定是要非常快的,这样给用户的第一感觉就是快、流畅;互联网公司的 App 则不是很关心启动速度,大部分互联网公司的应用都有一个启动页,用来展示广告或者功能介绍之类的,然后才会进入到主界面。需求不一样,这么做也无可厚非,不过从消费者的角度来看,越早见到主界面当然越好。
所以在做一个 Android App 的时候,一定要记得将应用的启动时间作为一个性能指标,毕竟
天下武功,唯快不破!
⑨ Android App启动时间测试方法总结
查看当前界面Activity的方法:
1)运行命令:adb shell mpsys window | findstr "mCurrentFocus"
mCurrentFocus=Window{227cb04 u0 com.oppo.music/com.oppo.music.MainListActivity}
从结果中可知:
当前应用包名:com.oppo.music
当前界面Activity:com.oppo.music.MainListActivity
2)查看应用的PID
adb shell ps | findstr “com.oppo.music”,找到PID对应的列
1、“高速摄像机或Iphone慢动作”查看应用的启动时间
1)使用高速相机或Iphone的慢动作(240ps)录制应用的启动视频
2)使用QucikTime的帧分析功能,确定好起始帧(手指按下抬起时)和结束帧(应用完全显示)
3)根据帧数计算启动时间:=1000*帧数量/240
备注:最接近真实用户使用场景,但是操作复杂,成本高
2、“ActivityManager”查看应用的启动时间
备注:系统main log中也会键世空有对应的显示(或adb shell logcat -b main | findstr ActivityManager)更佳
1)运行结果:
04-19 15:13:25.919 1181 1216 I ActivityManager: Displayed com.oppo.music/.MainListActivity: +677ms
04-19 15:13:33.556 1181 1216 I ActivityManager: Displayed com.oppo.music/.MainListActivity: +660ms
677ms和660ms就是music应用的启动时间
3、“WaitTime”查看应用的启动时间
测试方法:adb shell am start -W –S packagename/MainActivity命令
1)结果时间说明
ThisTime:一连串启动Activity的最后一个Activity开始算起始时间
TotalTime:一连串启动Activity的第一个Activity开始算起始时间
WaitTime:总的耗时,但是包括前一个应用 Activity pause 的时间和新应用启动的时间
说明:例如有的应用启动Activity的时候,会先显示一个白色的Activity,然后在显示正常Activity,这个时候TotalTime就是从第一个Activity启动作为起始时间,如果只有稿瞎一个Activity则ThisTime和TotalTime相等
总结:
如果只关心某个应用自身启动耗时,参考TotalTime;如果关心系统启动应用耗时,参考WaitTime;如果关心应用有界面Activity启动耗时,参考ThisTime
4、“am_activity_launch_time”查看应用启返陆动时间
测试方法:
1)开启系统的moblie log,例如mtk的moblie log,然后启动应用(或者adb shell logcat -b events | findstr am_activity_launch_time)
2)从moblie log中找到类似如下的event log:events_log_3__2019_0418_152200
3)搜索关键词:“am_activity_launch_time”,然后匹配对应的包名,如下:
04-18 15:21:28.365484 1181 1216 I am_activity_launch_time: [0,73476478,com.oppo.music/.MainListActivity,668,668]
04-18 15:21:37.295923 1181 1216 I am_activity_launch_time: [0,231925826,com.oppo.music/.MainListActivity,680,680]
4)应用的启动时间为668ms、680ms
5、Systrace查看应用的启动时间
1)抓取应用启动的trace文件
a、开发给的python脚本抓取,需要安装对应的python
b、打开android自带的monitor工具抓取,需要安装java环境和android sdk包
2)chrome浏览器输入chrome://tracing/,然后load对应的trace文件
3)搜索iq,如果能搜到说明正确抓取了trace文件,否则没有抓到启动时间点
4)找到应用对应的PID或包名的那一行
5)找到UI Thread那一行,然后可以使用【W】放大,【S】缩小,【A】左移,【S】右移,注意界面上的操作导航,需要选取对应的项才能使用快捷键
放大并移动找到activityStart那一列,选中该项并点击键盘【m】键可以查看阶段时间如下:
6)在activityStart下一行对应的handleLaunchActivity找到第一个draw,按下【ctrl】然后选中activityStart在选中draw,在按下【m】键,如下图:
7)从步骤5中可以看到,music的启动时间为458.656ms
备注:界面快捷键操作
6、adb脚本录屏方法(不一定有用,有的机器无该命令或–bugreport选项,且需要android API21+)
测试方法:
1)adb shell screenrecord –bugreport /sdcard/test.mp4
2)使用QuickTime分析视频即可,同方法1
备注:查看是否支持-bugreport选项
使用 adb shell screencap –help查看是否支持—bugreport选项
7、各种方法测试数据比较
⑩ Android app启动时间测试,使用ADB命令如何实现
直接写一个脚本使用adb命令控制app启动,然后使用截屏命令快速截屏最终将截屏结果的产生时间做分析即可