8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
用户希望APP可以快速响应并启动。如果APP启动较慢,则严重影响用户体验,甚至导致用户流失。
本文将讲述如何优化APP启动时间。本文首先阐述APP启动过程;然后讨论如何诊断APP启动性能问题;最后m描述一些常见的APP启动时间过慢的问题,并提出一些解决方法。
APP启动的内部原理
APP启动有3种启动方式:cold start,warm start,hot start。每种启动方式都会影响用户启动APP的时间。在cold start中,APP的启动需要从头开始。而对其他两种启动方式,系统只需要将正在运行的APP从后台加载到前台。我们建议总是假设以cold start方式作为优化对象。这样做也可以提高warm start 和 hot start的启动性能。
为了提高APP启动速度,需要理解在每种启动方式中系统和APP之间发生了什么,做了哪些交互。
Cold Start
Cold start是指APP需要从头开始启动,即在开始前,系统进程还没创建APP的进程。cold start一般是在这些情况下发生,即设备启动后或者APP被系统kill掉后,第一次启动APP。在这种类型的启动方式下,缩短启动时间是一个挑战,因为,与其他启动状态相比,系统和APP有更多的工作要做。
在cold start开始时,系统有三个任务。如下所示:加载并启动APP。
启动后立即显示APP的空白起始window。
创建APP进程。
只要系统创建了APP进程,APP就负责下一个阶段的工作。如下所示:创建APP对象。
启动主线程。
创建Main Activity。
加载View。
配置屏幕。
执行初始绘制。
一旦APP进程完成第一次绘制,系统进程便会将当前显示的背景窗口换掉,并将其替换为Main Activity。此时,用户就可以使用APP。
下图显示了系统和应用程序如何在彼此之间切换工作。
性能问题是在创建APP和创建Activity期间引起的。
创建Application
当你的应用程序启动时,空白的开始窗口将保留在屏幕上,直到系统第一次完成绘制应用程序。 此时,系统进程会为应用程序换掉启动窗口,允许用户开始与应用程序进行交互。
如果你在自己的应用程序中重载了Application.onCreate(),系统会调用你的Application的onCreate()方法。 之后,应用程序会创建主线程(也称为UI线程),并创建Main Activity。
创建Activity
APP进程创建Activity后,Activity执行以下操作:初始化values
调用构造方法
根据当前生命周期状态调用相应的方法,例如onCreate()方法。
通常,onCreate()方法对加载时间影响最大,因为它以最高开销执行工作:加载和扩充视图,以及初始化要运行的活动所需的对象。
Hot Start
应用程序的hot start方式比较简单,开销也比cold start低。在hot start过程中,系统只需要将你的Activity加载到前台。如果你的应用程序的所有Activity仍驻留在内存中,则该应用程序可以避免重复对象初始化,布局加载和渲染。
但是,如果某些内存为了响应某些事件(例如onTrimMemory())而被回收,则需要重新创建这些对象。
Hot start与cold start相同的是:在APP完成Activity的渲染之前,系统进程会显示一个空白的屏幕。
Warm Start
warm start 包含了cold start过程中的一些子集。同时,warm start 的开销比hot start低。许多潜在的状态都可以看成warm start。例如:用户退出APP,但又重启APP。此时,进程仍在运行,但是APP必须通过调用onCreate()从头开始创建Activity。
系统消耗了APP,然后用户重新启动。进程和Activity需要重新创建,但是任务可以从已保存的bundle中加载。
发现并诊断问题
Android提供了几种方法去发现并诊断APP中存在的问题。Android vitals可以提醒你APP出现了问题,诊断工具可以帮你检测问题所在。
Android vitals
Android vitals可以通过Play Console提醒你APP的启动时间过长,从而帮助提高应用的性能。在以下情况下, Android vitals认为你的应用程序的启动时间过长:cold startup 过程消耗5s或更长时间
warm startup 过程消耗2s或更长时间
hot startup 过程消耗1.5s或更长时间
诊断启动时间较慢的问题
为了正确确定APP启动时间性能,你可以跟踪显示启动应用程序所需时间。
初始化显示时间(Time to initial display)
在Android 4.4及以上系统,logcat会输出一个Displayed值。此值表示加载进程和完成在屏幕上绘制Activity之间所需要的时间。 在这段时间内,包含以下一系列事件:启动进程
初始化对象
创建并初始化Activity
加载布局
你一次绘制你的APP
Log一般显示如下:1ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms
在用Android studio查看Displayed时,需要禁用过滤器。因为是系统服务器为此提供服务。下图显示了如何禁用过滤器,以及显示了Displayed日志。
在Displayed值的时间内不一定加载并显示了所有资源。布局文件中未引用的资源或APP作为部分对象初始化的资源并没有加载。这是因为加载他们是内联过程(inline process),不会阻塞APP的初始化显示。
有时,Displayed这行日志会显示一些附加信息。例如:1ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)
你也可以使用adb命令查看你的APP启动的时间。如下所示:1
2
3
4adb [-d|-e|-s ] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN
控制台会输出以下内容:1
2
3
4
5
6Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete
-c和-a参数是可选的,指定相应的和。
完全显示时间(Time to full display)
你可以使用reportFullyDrawn()方法来测量应用程序启动和完整显示所有资源和视图层次结构之间所用的时间。
常见问题分析
本节讨论几个常见的影响APP启动性能的问题。这些问题主要涉及初始化app和Activity对象,以及屏幕的加载。
app初始化
当你重写Application类,执行繁重的任务,复杂的逻辑时,启动性能问题就会凸显出来了。如果你在自定义Application中执行暂时不需要的初始化,那么就会增加启动时间。有些初始化是完全不必要的。
Activity
一般在Activity的onCreate()方法中往往会处理很多耗时任务。布局太复杂
磁盘读写,网络I/O
加载并解码bitmap
栅格化VectorDrawable对象。
初始化Activity的其他子系统
解决方式如下:减少布局层级。使用,ViewStub, LinearLayout->RelativeLayout,ConstraintLayout等。常用工具Layout Inspector,Hierarchy Viewer。
异步加载资源;先加载部分View,对于比较耗时的,延迟加载
参考文档App Startup Time
Android性能优化典范