启动优化
启动的形式
- 冷启动(cold start)
- 热启动(warm start)
- 温启动(lukewarm start)
冷启动
冷启动表示一切从头开始,app的进程还未被创建。冷启动一般就是app首次启动出现。
冷启动刚开始时,系统将做3件事情:
- 加载并启动app
- app启动后,立即展示一个空白的启动window(一般不可见)
- 创建app进程
在app的进程创建后,app进程将负责后面的一些事情:
- 创建app对象
- 启动Main thread(UI thread)
- 创建Main Activity
- inflating views
- 布置屏幕
- 执行初始的绘制(draw)
一旦app的进程完成了首次的绘制,系统进程会将空白的启动window移除掉,用MainActivity替换。从此刻开始,用户就可以使用app了。
整个的流程如下:
Application的创建
当app启动时,空白的window将出现,直到app完成了绘制,在这个节点,系统进程间去掉空白window。
Activity的创建
在app进程创建了activity后,activity将执行下面一系列的操作:
- 初始化一些数值
- 调用构造函数
- 执行各种回调,如onCreate()
热启动
热启动就相对来说就简单很多,并且更快。它要做的只是将Activity从后台拉回到前台。只要app中的activity都在内存中,那样就可以避免重复的对象初始化,layout展开和绘制。
但是是如果由于内存的问题,导致Activity被移除,那么这些操作还是需要进行的。
个人的理解热启动的场景:
- 用户按home键将app置于后台
- 新的app覆盖了当前的app,如电话、app拉取第三方app、下拉notification
温启动
温启动在启动的时候已经有了在冷启动时的一些状态,而不需要进行重复的操作了。
什么样的场景算温启动:
- 用于通过返回键退出app,但是很快又重新打开(即表示未被系统彻底回收)。这时Activity需要重走onCreate()。
- app被系统从内存中移除,但是又被用户打开,这个时候app和Activity都需要重新走一遍,但是可以从保存的instance state nbundle中获取一些状态信息。
启动性能的测试
初始Display时间(对应上面Dispalyed Time)
这部分的时间是从启动app进程到完成对应activity的绘制这段时间,具体包括:
- 启动app进程(只有mainActivity会有这个时间!!)
- 对象的初始化
- 创建并初始化Activity
- inflate布局文件
- 布置和视图绘制
示例:
Time to full display
这个计算的时间是从启动app进程到activity完全的展示出来,包括资源的加载和视图层级的更新。
这个值主要的价值场景是懒加载的情况,懒加载是app不阻塞视图的绘制,但是会异步的加载资源和更新视图。最简单的就是image是从网路上获取的。
这个需要手动去获取,在完成的地方调用Activity里的reportFullyDrawn()
方法(注意只能调用1次)
启动优化的一些建议
1、避免application启动过重
- 异步初始化第三方组件,不阻塞主线程;或者延迟初始化,对于不是马上就需要使用的,可以延迟
- GC事件(这个在Dalvik时代是最严重的)、初始化的同时执行I/O方面的操作
2、避免Activity的过度初始化
- 过于复杂的布局文件
- load和decode bitmap
- disk操作和网络操作阻塞
- ...
对于布局文件,一般就是更优化的处理布局,另外就是使用ViewStub
对象来根据需要实时的inflate布局。
资源的懒加载或者其他线程加载。
3、启动主题切换
这个不是真正意义上的速度优化,只是给用户一种错觉。
将上面提到的空白window通过theme的方式替换成app的view,其实app并没有启动起来。
一个示例:
如何实现:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar" >
<item name="android:windowBackground">@drawable/branded_logo</item>
</style>
</resources>
4、诊断
- BlockCanary
- ANRWatchDog
- TraceView
其他
- 利用主题快速显示界面;
- 异步初始化组件;
- 梳理业务逻辑,延迟初始化组件、操作;
- 正确使用线程;
- 去掉无用代码、重复逻辑等。
- 多进程框架,只有主进程执行application的onCreate()逻辑