🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] 参加官方文档:[https://developer.android.com/topic/performance/vitals/launch-time?hl=zh-cn#top\_of\_page](https://developer.android.com/topic/performance/vitals/launch-time?hl=zh-cn#top_of_page) # 应用启动内部机制 应用有三种启动状态,冷启动中应用从头开始启动,其他状态下系统需要将后台运行的应用带入前台,我们在冷启动的基础上进行优化,可以最大限度的提升应用性能 ## 冷启动 出现场景: * 设备刚开机,启动应用时 * 系统终止应用进程(或用户手动划掉应用),再次重新打开时 冷启动分为三步: 1、加载并启动应用 2、在启动后立即显示应用的空白启动窗口 3、创建应用进程。系统首次完成应用绘制后,会换掉应用的空白启动窗口,展示具体的UI ![](https://img.kancloud.cn/e9/da/e9da638899d71a2b75ae313b3de26917_983x611.png) ## 热启动 出现场景: * 用户直接点击Home键回到主页或最近应用键到其他应用,再次返回本应用时 热启动中,系统的所有工作就是将后台的 Activity 带到前台。如果应用的所有 Activity 都还驻留在内存中,则应用可以无须重复对象初始化、布局扩充和呈现。热启动显示的屏幕上行为和冷启动场景相同,即系统进程显示空白屏幕,直到应用完成 Activity 呈现。 ## 温启动 出现场景: * 用户退出应用,但并未直接结束掉(划掉)进程 * 应用被回收,重新打开时(onCreate中会拿到回收时保存的实例状态) 温启动的开销比热启动多,用户退出应用,之后又重新启动,进程可能已经继续运行,但是Activity需要重新创建。 # 检测和诊断问题 应用启动时间过长时,Google Play管理中心可协助提醒我们,此情况在国内环境中暂不使用,但其标准可以做个参考。Android Vitals 在应用出现以下情况时将其启动时间视为过长: * 冷启动用了 5 秒或更长时间 * 温启动用了 2 秒或更长时间 * 热启动用了 1.5 秒或更长时间 ## 初步显示启动所用时间 在 Android 4.4(API 级别 19)及更高版本中,logcat 包括一个输出行,其中包含名为`Displayed`的值。此值代表从启动进程到在屏幕上完成对应 Activity 绘制所经过的时间。经过的时间包括以下事件序列: 1. 启动进程。 2. 初始化对象。 3. 创建并初始化 Activity。 4. 扩充布局。 5. 首次绘制应用。 报告的日志行类似于以下示例: ```plain ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms ``` 也可以使用 ADB Shell Activity Manager 命令运行应用来测量初步显示所用时间。 ## 完全显示启动所用时间 某些情况下Activity视图会出现延迟加载的情况,比如界面中网络请求获取到的图片就会因网络环境不同而延迟加载,我们可以在Activity中手动调用`reportFullyDrawn()`方法,来测量从应用启动到完全显示所有资源和视图层次结构所经过的时间。 # 问题和优化方案 ## 常见影响启动时间的问题 ### 1、密集型应用初始化 即在Application的onCreate方法中执行了过多操作。 优化解决方案: * 延迟初始化对象,仅初始化立即需要的对象 * 不要在Application中创建全局静态对象,而是移动到单例模式中 * 考虑使用依赖注入框架(如Dagger),在首次注入时创建对象和依赖项 ### 2、密集型Activity初始化 创建 Activity 通常需要进行大量的高开销工作,通常有机会优化这项工作以实现性能改进。通常视图层次结构越大,应用扩充它所花的时间就越长;并且在主线程初始化资源也可能会降低启动速度。 优化解决方案: * 减少冗余或嵌套布局,优化布局结构 * 不要扩充在启动期间无需显示的界面部分,考虑使用ViewStub对象在更合适的时机扩充 * 在子线程延迟部分资源的初始化 * 允许应用先加载并显示您的视图,稍后再更新依赖于位图和其他资源的可视属性 ## 启动白屏问题与优化 点击应用图标,打开App,创建应用进程时,系统会根据清单文件设置的主题颜色来展示一个白屏或黑屏,以给与用户反馈。当创建应用进程这一步耗时较长时,白屏或黑屏体验就很不好了,来看看相应的解决方案: ### 1、禁用系统进程绘制时的空白屏幕 将启动Activity的主题设置为如下即可: ```xml <style name="APPTheme" parent="@android:style/Theme.Holo.NoActionBar"> <item name="android:windowDisablePreview">true</item> </style> ``` 禁用系统进程绘制时的空白屏幕,可能导致启动时间更长,最重要的是用户点击了图标后,界面会无响应一段时间,没有相应的反馈。 ### 2、为启动Activity自定义主题背景 ```xml <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"> <!-- The background color, preferably the same as your normal theme --> <item android:drawable="@android:color/white"/> <!-- Your product logo - 144dp color version of your app icon --> <item> <bitmap android:src="@drawable/product_logo_144dp" android:gravity="center"/> </item> </layer-list> ``` ```xml <style name="APPTheme" parent="@android:style/Theme.Holo.NoActionBar"> <item name="android:windowBackground">@drawable/splash_icon</item> </style> ``` 为启动Activity设置以上主题,这样自定义的主题背景会替代掉默认的白屏或黑屏。