其他分享
首页 > 其他分享> > 探索 App 秒开的秘密 —— 启动性能优化,想提高开发效率的必看

探索 App 秒开的秘密 —— 启动性能优化,想提高开发效率的必看

作者:互联网

那么关键的问题是,用户很可能会因为从启动窗口到显示画面的过程耗时过长而感到厌烦,从而导致用户没有来得及等程序启动完毕就切换到其他 App 了。更严重的是,如果启动时间过长,可能导致程序出现 ANR。我们应该避免出现这两种糟糕的情况。

启动方式


Android 应用的启动方式分为三种:冷启动、暖启动、热启动,不同的启动方式决定了应用 UI 对用户可见所需要花费的时间长短。

顾名思义,冷启动消耗的时间最长。基于冷启动方式的优化工作也是最考验产品用户体验的地方。谈及优化之前,下面我们来看看这三种启动方式的应用场景,以及启动过程中系统都做了些什么工作。

冷启动

在安卓系统中,系统为每个运行的应用至少分配一个进程 (多进程应用申请多个进程) 。从进程角度上讲,冷启动就是在启动应用前,系统中没有该应用的任何进程信息 (包括 Activity、Service 等) 。

所以,冷启动产生的场景就很容易理解了,比如设备开机后应用的第一次启动,系统杀掉应用进程 (如:系统内存吃紧引发的 kill 和用户主动产生的 kill)后的再次启动等。那么自然这种方式下,应用的启动时间最长,因为相比另外两种启动方式,系统和我们的应用要做的工作最多。

应用发生冷启动时,系统有三件任务要做:

系统创建应用进程后,应用就要做下面这些事情:

只有当应用完成第一次绘制,系统当前展示的空白背景才会消失,才会被 Activity 的内容视图替换掉。也就是这个时候,用户才能和我们的应用开始交互。

下图展示了冷启动过程系统和应用的一个工作时间流:

![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUu
aW8vdXBsb2FkX2ltYWdlcy8yMDI2NDI3OC04NTZlMzQ4NDZmMjIxZjFh?x-oss-process=image/format,png)

launch time

这其中有两个 creation 工作,分别为 Application 和 Activity creation。从图中看出,他们均在 View 绘制展示之前。所以,在应用自定义的 Application 类和 第一个 Activity 类中,onCreate() 方法做的事情越多,冷启动消耗的时间越长。

暖启动

当应用中的 Activities 被销毁,但在内存中常驻时,应用的启动方式就会变为暖启动。

相比冷启动,暖启动过程减少了对象初始化、布局加载等工作,启动时间更短。但启动时,系统依然会展示一个空白背景,直到第一个 Activity 的内容呈现为止。

热启动

相比暖启动,热启动时应用做的工作更少,启动时间更短。热启动产生的场景很多,常见如:用户使用返回键退出应用,然后马上又重新启动应用。

启动时间


从技术角度来说,当用户点击桌面图标开始,系统会立即为这个 App 创建独立的专属进程,然后显示启动窗口,直到 App 在自己的进程里面完成了程序的创建以及主线程完成了 Activity 的初始化显示操作,再然后系统进程就会把启动窗口替换成 App 的显示窗口。

start process

上述流程里面的绝大多数步骤都是由系统控制的,一般来说不会出现什么问题,可是对于启动速度,我们能够控制并且需要特别关注的地方主要有三处:

Application 的 onCreate 流程,对于大型的 App 来说,通常会在这里做大量的通用组件的初始化操作。

Activity 的 onCreate 流程,特别是 UI 的布局与渲染操作,如果布局过于复杂很可能导致严重的启动性能问题。

目前有部分 APP 会提供自定义的启动窗口,这里可以做成品牌宣传界面或者是给用户提供一种程序已经启动的视觉效果。

Display Time

在正式着手解决问题之前,我们需要掌握一套正确测量评估启动性能的方法。所幸的是,Android 系统有提供一些工具来帮助我们定位问题。

从 Android 4.4(API 19)开始,Logcat 自动帮我们打印出应用的启动时间。这个时间值从应用启动(创建进程)开始计算,到完成视图的第一次绘制(即 Activity 内容对用户可见)为止。如:

display time

统计启动时间

如果是本地调试的话,统计启动时间还是很简单的,通过命令行方式即可:

$ adb shell am start -w <包名>/activity

输出的结果类似于:

$ adb shell am start -W com.jeanboy.app.test/com.jeanboy.app.test.HomeActivity

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.jeanboy.app.test/.HomeActivity }

Status: ok

Activity: com.jeanboy.app.test/.HomeActivity

ThisTime: 496

TotalTime: 496

WaitTime: 503

Complete

返回从 startActivity 到应用第一帧完全显示这段时间。就是总的耗时,包括前一个应用 Activity pause 的时间和新应用启动的时间;

标签:必看,探索,启动,App,系统,冷启动,应用,Activity,进程
来源: https://blog.csdn.net/m0_66265052/article/details/122627560