在二十一世纪,一切追求“快”的时代,无论是电子产品、手机系统还是APP,都在向“快”靠拢;因为紧张的生活令大家没有大把的时间沉下心来,去享受且感受其他事物。比如说我们去一家餐厅吃饭,在点餐的时候等了半天都没有服务人员过来,可能就没有耐心等待直接走了。
对于App来说,也是同样如此,如果用户点击App后,半天都打不开,用户就可能失去耐心卸载应用。所以,启动速度对于APP来说十分重要,启动速度是用户对一款App的第一体验,打开应用后才能去使用其中提供的强大功能,就算我们应用的内部界面设计的再精美,功能再强大,如果启动速度过慢,用户第一印象就会很差。因此,拯救App的启动速度,迫在眉睫。下面,我们来一起探索下提升 App启动速度的奥秘吧!
一、应用启动流程
从技术角度来说,当用户点击桌面图标开始,系统会立即为这个App创建独立的专属进程,然后显示启动窗口,直到App 在自己的进程里面完成了程序的创建以及主线程完成了Activity的初始化显示操作,再然后系统进程就会把启动窗口替换成App 的显示窗口。
(一) App启动的整个过程,可以分解成下面几个过程:
1、用户在Launcher上点击App Icon
2、系统为App创建进程,显示启动窗口,创建应用进程信息
3、App在进程中创建自己的组件
- 初始化应用中的对象(比如 Application 中的工作);
- 启动主线程(UI 线程);
- 创建第一个 Activity;
- 加载内容视图(Inflating);
- 计算视图在屏幕上的位置排版(Laying out);
- 绘制视图(draw);
只有当应用完成第一次绘制,系统当前展示的空白背景才会消失,才会被Activity的内容视图替换掉。也就是这个时候,用户才能和我们的应用开始交互。这个过程可以用下面这幅图来描述:
上述流程里面的红色框部分是由系统控制的,跟ROM相关的,我们无法处理。对于启动速度,我们能够控制的是Application的创建过程,所以需要特别关注的地方主要有三处。
(二) Application的创建过程,需要特别关注的三处:
1、Application
Application的onCreate流程,对于大型的App来说,通常会在这里做大量的通用组件的初始化操作。
2、Activity
Activity的onCreate流程,特别是UI的布局与渲染操作,如果布局过于复杂很可能导致严重的启动性能问题。
3、闪屏(主题)
修改主题优化启动时白屏/黑屏,这里可以做成品牌宣传界面或者是给用户提供一种程序已经启动的视觉效果。
二、启动时间的测量
(一) DisplayTime和requestFullyDrawn
在API19之后,Android在系统Log中打印,通过过滤ActivityManager以及Displa这两个关键字,可以找到系统中的这个Log:
$ adb logcat | grep “ActivityManager”
ActivityManager: Displayed com.example.launcher/. LauncherActivity: +999ms
ActivityManager: Fully drawn com.example.launcher/. LauncherActivity: +1s999ms
1、DisplayTime和requestFullyDeawn的区别
DisplayTime:这个时间,实际上是Activity启动,到Layout全部显示的过程,但是要注意,这里并不包括数据的加载,因为很多App在加载时会使用懒加载模式,即数据拉取后,再刷新默认的UI。
requestFullyDrawn:是由开发人员手动调用的,一般在数据全部加载完毕后。
(二) 计算启动时间——adb命令
adb shell am start -W packagename/主activity的全路径
例如:
adb shell am start -W com.hx.clent/com.yt.hxmobile.MainActivity
➜ ~ adb shell am start -W com.xys.preferencetest/.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.xys.preferencetest/.MainActivity }
Status: ok
Activity: com.xys.preferencetest/.MainActivity
ThisTime: 1047
TotalTime: 1047
WaitTime: 1059
Complete
WaitTime:返回从 startActivity 到应用第一帧完全显示这段时间。就是总的耗时,包括前一个应用 Activity pause 的时间和新应用启动的时间;
ThisTime:表示一连串启动 Activity 的最后一个 Activity 的启动耗时;
TotalTime:表示新应用启动的耗时,包括新进程的启动和 Activity 的启动,但不包括前一个应用 Activity pause 的耗时。 开发者一般只要关心 TotalTime 即可,这个时间才是自己应用真正启动的耗时。
三、优化思路
作为普通应用,App进程的创建等环节我们是无法主动控制的。开发人员唯一能做的就是在Application 和 第一个 Activity 中,减少 onCreate() 方法的工作量,从而缩短冷启动的时间。像应用中嵌入的一些第三方 SDK,都建议在 Application 中做一些初始化工作,开发人员不妨采取懒加载的形式移除这部分代码,而在真正需要用到第三方 SDK 时再进行初始化。
以上内容就是App的启动优化,其重点过程依然是分析耗时的操作,以及如何设计合理的启动顺序,希望以上内容能够帮助到各位;另外,利用工具来辅助我们的工作也很重要,尤其是开发APP的朋友们,每天面对各种代码,也是身心俱疲;并且工具的精准性,一点不比人为的弱,比如说友盟,功能齐全且简单易上手。
友盟的U-APM功能,在崩溃捕获、崩溃分析、错误分布、错误详情、细查结果、用户行为、监控警告,云真机的测试能力、智能诊断、行为分析、启动分析、卡顿分析、页面监控、网络分析、内存优化做的非常强大、对比竞品来说有明显优势,强烈推荐Android开发人员使用友盟U-APM,深入了解应用的性能和稳定性,集成简单、服务有保障,帮助您高效提升应用质量,让你的app变得如此丝滑!