Android 项目优化(五):应用启动优化

介绍了前面的优化的方案后,这里咱们在针对应用的启动优化作一下讲解和说明。html

1、App启动概述

一个应用App的启动速度可以影响用户的首次体验,启动速度较慢(感官上)的应用可能致使用户再次开启App的意图降低,或者卸载放弃该应用程序。android

应用程序启动有主要分为两种状态,每种状态都会影响应用程序对用户可见所需的时间:冷启动,热启动。shell

  • 冷启动:冷启动表示用户首次打开应用,这时进程还没建立,包含了Application建立的过程。冷启动时间指从第一次用户点击Launcher中的应用图标开始,到首页内容所有展现出来。
  • 热启动:热启动表示用户在首页按了返回,首页Activity已经Destroy,不过Application仍在内存中存在,对应的进程并无被杀掉,不包含Application建立过程。热启动时间指在Application仍然存在的状况下,从用户点击桌面图标,到首页内容所有展现出来。

注:冷启动、热启动不是官方的定义,而是咱们基于用户的角度考虑的定义。网络

在冷启动开始时,系统有三个任务。这些任务是:布局

  1. 加载并启动应用程序。
  2. 启动后当即显示应用程序空白的启动窗口。
  3. 建立应用程序进程。

一旦系统建立应用程序进程,应用程序进程就会负责下一阶段。这些阶段是:性能

  1. 建立App对象
  2. 启动主线程(main thread)
  3. 建立应用入口的Activity对象
  4. 填充加载布局Views
  5. 在屏幕上执行View的绘制过程.measure -> layout -> draw

应用程序进程完成第一次绘制后,系统进程会交换当前显示的背景窗口,将其替换为主Activity。此时,用户能够开始使用该应用程序。优化

这里咱们建议始终根据冷启动的假设进行优化。这样作也能够改善热启动的性能。ui

2、冷启动视觉效果优化

上面咱们说了,冷启动的阶段执行的操做为:spa

  1. 加载并启动应用程序
  2. 启动后当即显示应用程序空白的启动窗口
  3. 建立应用程序进程

如今 App 应用启动都会先进入一个闪屏页(LaunchActivity) 来展现应用信息。线程

系统默认会在启动应用程序的时候启动空白窗口 ,直到 App 应用程序的入口Activity建立成功,视图绘制完毕。可是存在的问题就是在进入闪屏页的时候,会有2秒左右的白屏/灰屏的界面。

为了更顺滑无缝衔接咱们的闪屏页,能够在启动 Activity 的 Theme中设置闪屏页图片,这样启动窗口的图片就会是闪屏页图片,而不是白屏。配置代码以下:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/lunch</item>  //闪屏页图片
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">false</item><!--显示虚拟按键,并腾出空间-->
</style>

这样设置的话,就会在冷启动的时候,展现闪屏页的图片,等App进程初始化加载入口 Activity (也是闪屏页) 就能够无缝衔接。

其实这种方式并无真正的加速应用进程的启动速度,而只是经过用户视觉效果带来的优化体验。

备注:上面的方案适用于闪屏页为整张图片为闪屏内容(闪屏页图片推荐.9格式,防止拉伸失真)。不适用于闪屏页为多个元素混合的。后者推荐参考 Android 项目优化(二):启动页面优化

 

3、App冷启动耗时统计

App冷启动耗时统计方式主要是:adb 命令统计、系统日志统计。

1. adb 命令统计

adb命令 : adb shell am start -S -W 包名/启动类的全限定名 , -S 表示重启当前应用。示例以下:

C:\Android\Demo>adb shell am start -S -W com.example.moneyqian.demo/com.example.moneyqian.demo.MainActivity
Stopping: com.example.moneyqian.demo
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.moneyqian.demo/.MainActivity }
Status: ok
Activity: com.example.moneyqian.demo/.MainActivity
ThisTime: 2247
TotalTime: 2247
WaitTime: 2278
Complete

 

ThisTime : 最后一个 Activity 的启动耗时(例如从 LaunchActivity - >MainActivity「adb命令输入的Activity」 , 只统计 MainActivity 的启动耗时)
TotalTime : 启动一连串的 Activity 总耗时.(有几个Activity 就统计几个)
WaitTime : 应用进程的建立过程 + TotalTime .

总结一下 : 若是须要统计从点击桌面图标到 Activity 启动完毕,能够用WaitTime做为标准,可是系统的启动时间优化不了,因此优化冷启动咱们只要在乎 ThisTime 便可。

2. 系统日志统计

根据系统日志来统计启动耗时,在Android Studio中查找已用时间,必须在logcat视图中禁用过滤器(No Filters)。由于这个是系统的日志输出,而不是应用程序的。

好比咱们能够经过过滤displayed输出的启动日志. 示例以下:

4、冷启动 Application 优化

咱们知道有不少第三方组件(包括App应用自己)都在 Application 中完成初始化操做。可是在 Application 中完成繁重的初始化操做和复杂的逻辑就会影响到应用的启动性能。

经过分析一下,咱们能够知道仍是有机会优化这些工做以实现冷启动的性能改进的,分析后发现影响冷启动时间的常见问题以下:

  • 复杂繁琐的布局初始化
  • 阻塞主线程 UI 绘制的操做,如 I/O 读写或者是网络访问.
  • 其它占用主线程的操做

咱们能够根据这些组件的轻重缓急之分,对初始化作一下分类 :

  • 必要的组件必定要在主线程中当即初始化(入口 Activity 可能当即会用到)
  • 组件必定要在主线程中初始化,可是能够延迟初始化。
  • 组件能够在子线程中初始化。

在进行优化的时候,须要注意如下几种状况:

  • 放在子线程的组件初始化建议延迟初始化,这样就能够了解是否会对项目形成影响! 
  • 将须要在主线程中初始化可是能够不用当即完成的动做延迟加载(初始化放在 Application 中统一管理为妙,不建议放在Activity里面)
  • 能够尝试将常见的组件库,例如 Bugly,x5内核初始化,SP的读写,友盟等组件放到子线程中初始化。(子线程初始化不能影响到组件的使用)

在优化好启动时间后,咱们就能够在针对闪屏页的时间,进行调整优化,具体公式为:

闪屏页展现总时间 = 组件初始化时间 + 剩余展现时间
相关文章
相关标签/搜索