Android app启动优化

前言

本文是本人学习Android app 启动优化的总结,由于本人知识有限,难免有错误或疏漏的地方,请大家多多指正。

为什么要学习APP的启动优化?

用户希望应用能够及时响应并快速加载。启动时间过长的应用可能会导致用户在对应用给出很低的评分,甚至完全弃用。

APP 启动流程简述

首先我们先简单描述一下App的启动流程(以冷启动为例,什么是冷启动下面会有讲解)
(1)用户点击桌面上的app Icon,Launcer进程采用Binder IPC方式向system_server发送startActivity请求
(2)system_server进程接收到请求后,向zygote进程发送创建App进程的请求
(3)Zygote进程fork出新的子进程,即App进程
(4)App进程通过 Binder IPC方式向system_server 发送attachApplication请求
(5)system_server接收到相关请求后,做出一系列的准备工作,通过Binder IPC向App进程发送scheduleLaunchActivity的请求
(6)App进程的binder线程(即ActivityThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息
(7)主线程在收到message后,通过反射的方式创建相关的Activity,并回调Activity的onCreate等方法
(8)至此,App便正式启动,开始进入Activity的生命周期,执行完onCreate/onStart/onResume,渲染完UI界面后便可以看到App的主界面。


image.png

App的启动类型

冷启动:冷启动是指App从头开始启动,系统进程在冷启动时才会创建App进程。发生冷启动的情况发生自系统启动后第一次开启应用和应用彻底结束后的再一次打开。
热启动:在热启动时,所有的工作就是将App带到前台。只要应用的所有Activity仍滞留在内存中,应用就不会重复执行对象的初始化、布局加载和绘制。
温启动:温启动包含了冷启动的部分操作,同时,他的开销比热启动要高。与许多状态可以被视为温启动。
(1)用户在退出应用后马上再次重启应用,此时App的进程还没有被销毁,继续运行,但应用需要重新开始从onCreate重新创建Activity。
(2)系统将应用从内存中释放,然后用户又重新启动它。进程和 Activity 需要重启,但传递到 onCreate() 的已保存的实例savedInstanceState对于完成此任务有一定助益。

启动耗时统计

在性能测试中遵循2-5-8原则:
当App启动的响应时间小于2s,客户认为app启动速度很快
当App启动的响应时间介于2-5秒之间,客户认为app启动速度还可以
当App启动的响应时间介于5-8秒客户认为app启动速度很慢,但还可以接受
当App启动的响应时间大于8秒,客户认为app启动速度是不可接受的,甚至认为App没有响应。
测试App的启动耗时统计主要有如下的两种方法
(1)系统日志统计
在Android 19版本以上,每次启动时都会打印开启app启动时间的名为Displayed的值。该值代表此值代表从启动进程到在屏幕上完成对应 Activity 的绘制所用的时间。


image.png

(2)命令方式统计
adb shell am start -S -W [packageName]/[activityName]


image.png

WaitTime:包括前一个应用Activity pause的时间和新应用启动的时间;(这一个在我的设备上没有相关的数据打印)
ThisTime:表示一连串启动Activity的最后一个Activity的启动耗时;
TotalTime:表示新应用启动的耗时,包括新进程的启动和Activity的启动,但不包括前一个应用Activity pause的耗时。
image.png

如何进行启动时间的性能调优

注意:其实这个话题对我这种初学性能调优的人来说肯定是说不了很全面,甚至可能有一些是错误的,下面的内容我将结合我所知道的相关知识进行讲述

如果对启动时间不满的话,就需要分析启动时间上的瓶颈。这时就需要借助Android Studio的CPU Profile了。使用方式如下
(1)点击app,选择Edit Configurations

image.png

(2)选择右侧Profiling选项卡,勾选Start recording CPU activity on startup 旁边的复选框,选择CPU的记录配置,共有四种配置,分别是
Sample Java Methods
对 Java 方法采样:在应用的 Java 代码执行期间,频繁捕获应用的调用堆栈。分析器会比较捕获的数据集,以推导与应用的 Java 代码执行有关的时间和资源使用信息。如果应用在捕获调用堆栈后进入一个方法并在下次捕获前退出该方法,分析器将不会记录该方法调用。如果您想要跟踪生命周期如此短的方法,应使用检测跟踪。

Trace Java Methods
跟踪 Java 方法:在运行时检测应用,以在每个方法调用开始和结束时记录一个时间戳。系统会收集并比较这些时间戳,以生成方法跟踪数据,包括时间信息和 CPU 使用率。

Sample C/C++ Functions
对 C/C++ 函数采样:捕获应用的原生线程的采样跟踪数据。要使用此配置,您必须将应用部署到搭载Android 8.0(API 级别 26)或更高版本的设备上。

Trace System Calls
跟踪系统调用:捕获非常翔实的细节,以便您检查应用与系统资源的交互情况。您可以检查线程状态的确切时间和持续时间、直观地查看所有内核的 CPU 瓶颈在何处,并添加要分析的自定义跟踪事件。要使用此配置,您必须将应用部署到搭载 Android 7.0(API 级别 24)或更高版本的设备上。此跟踪配置在 systrace 的基础上构建而成。您可以使用 systrace 命令行实用程序指定除 CPU Profiler 提供的选项之外的其他选项。systrace 提供的其他系统级数据可帮助您检查原生系统进程并排查丢帧或帧延迟问题。

在这里选择Trace Java Methods。点击apply


image.png

(3)在运行时直接点击Profile即可


image.png

(4)在主页能够完全显示且具备交互能力(或者你自己觉得合适的时机)后点击stop,停止CPU的监控,这时会解析相关的Trace Record


image.png

image.png

(5)此时展示分析后的结果
image.png

那么这个如何进行分析呢?首先看一下相关的几个分析方法

Flame Chart
提供一个倒置的调用图表,用来汇总完全相同的调用堆栈。也就是说,将具有相同调用方顺序的完全相同的方法或函数收集起来,并在火焰图中将它们表示为一个较长的横条 。横轴显示的是百分比数值。由于忽略了时间线信息,Flame Chart 可以展示每次调用消耗时间占用整个记录时长的百分比。 同时纵轴也被对调了,在顶部展示的是被调用者,底部展示的是调用者。此时的图表看起来越往上越窄,就好像火焰一样,因此得名: 火焰图。

image.png

Top Down Tree
如果我们需要更精确的时间信息,就需要使用 Top Down Tree。 Top Down Tree显示一个调用列表,在该列表中展开方法或函数节点会显示它调用了的方法节点

image.png

Bottom Up Tree
方便地找到某个方法的调用栈。在该列表中展开方法或函数节点会显示哪个方法调用了自己。就是Top Dwon Tree的倒置

image.png

一般我们在这三种图中,只要看Top Down Tree就好

那么如何进行启动时间的优化呢?我认为可以采取如下几步
(1)首先找耗时最多的方法,点进看这个方法调用中那个方法调用耗时长
(2)如果耗时长的方法层级很深且都是在调用系统的方法那么这个方法可能是我们无法进行优化的,在去寻找第二长的方法链进行调用
(3)一般可以在主界面调用onCreate进行分析

简单例子分析

现在我们以一个简单的例子来分析一下如何进行app的启动优化。
(1)首先我们看一下app的启动时间
根据启动时间我们可以看到冷启动该app耗费了3.4s


image.png

(2)打印CPU的Profile,可以看到
在onCreate中调用了sleep方法,该方法耗时为3.2s


image.png

(3)查看源码发现在MainActivity的onCreate方法中调用了SystemClock.sleep方法进行了休眠。
image.png

(4)去除休眠后我们在打印启动时间,发现启动速度有了很大的提升(这是因为我们故意睡眠了3s,实际上可能提升的速度很轻微,甚至看不出来。)
image.png

至此Android app启动时间优化介绍完成。相关的实战将在介绍完布局优化后以单独的文章进行介绍。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 用户希望应用能够及时响应并快速加载。启动时间过长的应用可能会导致用户在对应用给出很低的评分,甚至完全弃用。 启动状...
    zcwfeng阅读 2,996评论 1 28
  • App启动分为冷启动和热启动 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应...
    wenou阅读 334评论 2 1
  • 朝阳杨少爷(ID:CY_YANG_DA_YE),专注于Android领域的开发者、分享者。 背景 我们的APP新版...
    Demo_Yang阅读 1,630评论 4 15
  • 知其然知其所以然 凡是不知道的事情,查文档,肯定能查出个究竟了解启动时,系统和应用程序发生了什么,以及他们在这些状...
    Natchi阅读 752评论 0 0
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,030评论 0 4