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

一、App启动概述

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

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

  • 冷启动:冷启动表示用户首次打开应用,这时进程还没创建,包含了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。此时,用户可以开始使用该应用程序。

这里我们建议始终根据冷启动的假设进行优化。这样做也可以改善热启动的性能。

二、冷启动视觉效果优化

上面我们说了,冷启动的阶段执行的操作为:

  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 项目优化(二):启动页面优化

三、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输出的启动日志. 示例如下:

四、冷启动 Application 优化

我们知道有很多第三方组件(包括App应用本身)都在 Application 中完成初始化操作。但是在 Application 中完成繁重的初始化操作和复杂的逻辑就会影响到应用的启动性能。

通过分析一下,我们可以知道还是有机会优化这些工作以实现冷启动的性能改进的,分析后发现影响冷启动时间的常见问题如下:

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

我们可以根据这些组件的轻重缓急之分,对初始化做一下分类 :

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

在进行优化的时候,需要注意以下几种情况:

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

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

闪屏页展示总时间 = 组件初始化时间 + 剩余展示时间

Android 项目优化(五):应用启动优化的更多相关文章

  1. android 项目学习随笔四(优化ViewPager)

    1.不能滑动的ViewPager import android.content.Context; import android.support.v4.view.ViewPager; import an ...

  2. EntityFramework优化:第一次启动优化

    1. 预先生成视图 通过代码的方式来预先生成视图,要求EntityFramework是6.0及以上版本. 控制台程序: using System.Data.Entity.Infrastructure; ...

  3. Android 学习第9课,java android 项目的安装与启动过程

    android 安装过程: 开发工具先把.java文件转换成.class,然后转换成dx,再签名打包成apk,最后在设备上执行 adb install c:\xxx.apk android 启动过程: ...

  4. Android项目开发五-《星星生活志》1.使用MediaRecorder录制音频

    Android设备实现录制音频的简单demo 转载请注明; http://blog.csdn.net/u013670933/article/details/26089487 代码例如以下: publi ...

  5. 嵌入式Linux启动优化手记2&nbsp;U…

    参考一下 原文地址:U-boot优化">嵌入式Linux启动优化手记2 U-boot优化作者:ZhaoJunling 既然不能使用新的U-boot,那就优化一点是一点,慢慢干吧. 1. ...

  6. Android 项目优化(七):阿里巴巴Android开发手册整理总结

    本来之前觉得Android项目优化系列的文章基本整理完毕了,但是近期看了一下<阿里Android开发手册>有了很多收获,想再整理一篇,下面就开始吧. 先在这里列一下之前整理的文章及链接: ...

  7. Android 项目优化(三):MultiDex 优化

    在整理MultiDex优化之前,先了解一下Apk的编译流程,这样有助于后面针对MultiDex优化. 一.Apk 编译流程 Android Studio 按下编译按钮后发生了什么? 1. 打包资源文件 ...

  8. Android 性能优化 ---- 启动优化

    Android 性能优化 ---- 启动优化 1.为什么要进行启动优化 一款应用的第一印象很重要,第一印象往往决定了用户的去留.打开一款应用,如果速度很快,很顺畅,那么很容易让人觉得这款应用背后的技术 ...

  9. Android内核开发:系统启动速度优化-Android OS启动优化(转)

    Android系统的启动优化主要分为三大部分: (1) Bootloader优化 (2) Linux Kernel的剪裁与优化 (3) Android OS部分的剪裁与优化 本文重点关注Android ...

随机推荐

  1. Sql 修改表结构

    添加字段 alter table 表名 add 字段名 nvarchar(100) not null 修改字段 alter table 表名 alter column 字段名 int not null ...

  2. Ubuntu 16.04 安装最新稳定版Nginx 1.6.0

    Ubuntu 16.04 默认安装的是nginx 1.14.0 #默认安装方式:apt-get  install nginx   1.查看是否安装nginx,如果已经安装,请先卸载 #查看安装版本 d ...

  3. 【数据结构】之散列链表(Java语言描述)

    散列链表,在JDK中的API实现是 HashMap 类. 为什么HashMap被称为“散列链表”?这与HashMap的内部存储结构有关.下面将根据源码进行分析. 首先要说的是,HashMap中维护着的 ...

  4. 【数据结构】之链表(C语言描述)

    链表是线性表的一种,是一种物理存储单元上非连续的存储结构,链表中的数据元素之间是通过指针链接实现的. 链表由一系列节点组成,节点可以在运行时动态的生成. 链表中国的每个节点分为两部分:一部分是存储数据 ...

  5. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(4)- OTP及其烧写方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的OTP. 在i.MXRTxxx启动系列第二篇文章 Boot配置(ISP Pin, OTP) 里痞子 ...

  6. 大规模机器学习在LinkedIn预测模型中的应用实践

    预测模型在 LinkedIn 的产品中被广泛应用,如 Feed.广告.工作推荐.邮件营销.用户搜索等.这些模型在提升用户体验时起到了重要的作用.为了满足建模需求,LinkedIn 开发并且开源了 Ph ...

  7. shell ssh 远程机器 追加文件内容

    在host1上,把下面的两行内容通过ssh追加到host2上的/etc/ca-certificates.conf文件中 I am a student Are you ok ssh host2 &quo ...

  8. js练习-两个栈实现队列

    目录 题 解 题 现在有个Q队列和栈A,栈B,栈只有两个方法,push()和pop(), 队列也只有两个方法,push()和pull(),队列的进和出都只能通过A和B的push和pop实现. // 大 ...

  9. aplipay支付-app支付之前后端实现

    目录 前言 一 前台aplipay实现 1.1 安装0x5e/react-native-alipay 1.2. 配置 1.3. Alipay.pay(orderStr) 二 后端 2.1 服务端sdk ...

  10. linux gre隧道创建

    目录 linux gre隧道创建 实验环境 实验目的 实验步骤 1.在host A(10.10.10.47)上面操作 2.在host B(192.168.0.118)上面操作 实验结果 还原实验环境 ...