1、说明
其实这篇博客本来想将题目命名为:“我的 Android 性能优化总结”,只是想简单总结一下一路走来经历的性能优化,并从启动、绘制、内存、稳定性和 Hybrid 优化几个方面简单做一个概括总结,但是发现越写越多。想了想还是分开几篇来写吧,这是优化系列的第1篇,对启动化做一些分析。
2、冷启动 & 热启动
App 的启动一般分为冷启动和热启动:
- 冷启动:App 在后台被杀死,该状态下打开 App 即为冷启动。
- 热启动:与冷启动相反,App 未被杀死进程,仍在后台运行,该状态下再启动即为热启动(注意:我们按返回键退出所有页面后关闭 App,这个时候进程还在后台运行着,并未完全杀死,只是系统会在一段时间后杀死进程并回收内存)。
3、原因
- 启动页面布局复杂,延迟初始化。
- Application 启动时有耗时操作。
- 启动页面启动时有耗时操作。
4、优化
1、精简布局
布局太复杂或层级太深会加大页面计算绘制时间,启动页面最好不要直接放太多东西,这样可以在一定程度上减少启动时间。
2、异步/延迟初始化
在应用开发过程中往往需要添加很多的第三方插件依赖,而这些依赖往往需要在 Application 初始化或页面初始化时进行初始化操作,当依赖的库很多的时候就会造成比较大的耗时,我们可以对其做一些异步化,这样可以避免占用主线程,可以有效减少启动时间。
这里着重说一下 IntentService,它是继承自 Service 并处理异步请求的一个类,在其内部有一个工作线程来处理耗时任务。启动 IntentService 和启动传统的 Service 一样,同时,当任务完后,IntentService 会自动停止,而不需要去手动控制。对于异步初始化处理,这个类很好用。
工具方面,我们可以通过 TraceView、Systrace、Android Profiler 等工具分析耗时方法,从而做出有针对性的处理。
3、设置 Theme
当系统加载 Activity时,onCreate 其实是一个比较耗时的操作,系统为了让用户能有一个比较好的体验,实际上会绘制一些初始化界面来做占位。具体的过程是系统会首先读取 Activity 的 Theme 属性,当 Activity 加载完毕后替换真正的页面。
我们在开发中肯定或多或少也会遇到过:如果不设置 Theme 属性,启动应用时会有白屏的现象,这种情况可能在 Release 包情况下不太明显,因为它做了很多优化,但在 Debug 包情况下会比较明显。当然,这是建立在有一定初始化耗时情况下,如果你是一个新创建的项目,根本没有什么初始化的东西这个效果就不太明显了。
使用该方法设置后,虽然不能减少应用的启动时间,但可以在一定程度上减少白屏,也可以提升用户体验。
5、检测 - 是否需要优化
了解了造成启动慢的原因和怎样优化后,我们肯定想知道怎样检测这个应用是否需要优化呢 ?
基本通过2种方案:
- 人体检测:我去,怎么还有这种检测方法呢 ? 其实就是肉眼感知是否启动等待时间是否很长,是否有白屏或黑屏现象。
- adb 命令计算启动时间:一般启动时间最好不要超过3s,否则会有较长的等待感。
adb 计算启动时间命令:
// 命令输入
adb shell am start -W com.haoyd.sample/.IndexActivity
// 自动输出
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.haoyd.sample/.IndexActivity }
Status: ok
Activity: com.haoyd.sample/.IndexActivity
ThisTime: 1054
TotalTime: 1054
WaitTime: 1097
Complete
com.haoyd.sample 是包名,后面的 /.IndexActivity 是你需要启动的页面路径,如果是放在文件夹下,需要把包名下的文件夹路径写全了。
解释一下输出的几个参数:
- ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。一般看这个就可以。
- TotalTime:应用的启动时间,包括:创建进程 + Application 初始化 + Activity 初始化到界面显示。
- WaitTime:一般比TotalTime大点,包括系统影响的耗时。
6、总结
在该篇文章中对冷热启动做了部分简介,并介绍了启动耗时原因、优化方法和检测方法,算是对自己的一个总结,也希望能对想了解启动优化的同学有一些帮助。