简述:
APP的启动流程:
- 加载启动App
- App启动之后立即展示出一个空白的Window
- 创建App的进程
- 创建App对象启
- 动Main Thread创
- 建启动的Activity对象
- 加载View
- 布置屏幕
- 进行第一次绘制
作为普通应用,App进程的创建等环节我们是无法主动控制的,可以优化的也就是Application、Activity创建以及回调等过程
Google给出的启动加速的方向:
- 利用提前展示出来的Window,快速展示出来一个界面,给用户快速反馈的体验;
- 避免在启动时做密集沉重的初始化(Heavy app initialization);
- 定位问题:避免I/O操作、反序列化、网络操作、布局嵌套等。
备注:方向1属于治标不治本,只是表面上快;方向2、3可以真实的加快启动速度。
综上所述,应用的启动性能主要问题在以下两方面:
1)Application 初始化开销大
Application 的创建过程中,如果执行复杂的逻辑或者初始化大量的对象,将会影响应用的启动体验。比如:
- 初始化 MainActivity 的状态信息;
- 创建了大量临时变量导致 GC(GC 在 ART 下影响很小);
- 执行磁盘 I/O操作(这甚至就会直接阻塞应用的执行);
- 反序列化操作;
- 多重循环等等。
2)Activity 初始化开销大
Activity 的创建中除了要避免 Application 创建中提到的问题,还需要注意以下问题:
- 加载极其复杂的布局主线
- 程中出现磁盘或网络 I/O
- 加载和解码 Bitmap
- 渲染多个 VectorDrawable 对象
常用解决方法:
- 层次过深:
减少冗余、嵌套的布局层次。
不绘制不可见的 UI,而是使用 ViewStub 对象在适当的时间布局绘制。 - 大量的资源初始化:
调整资源初始化的位置,可以在不同的线程执行懒加载。
延迟初始化组件、操作;
加载部分视图,然后再加载大的位图和其他资源。
使用网络数据缓存,对于多个接口的同时访问,可以合并 - 启动界面:
使用 Activity 的 windowBackground 属性
使用闪屏页 - 去掉无用代码、重复逻辑等
- 巧用线程:ThreadPoolExecutor比Thread更加高效、优势明显,但是特定场景下单个时间点的表现Thread会比ThreadPoolExecutor好:同样的创建对象,ThreadPoolExecutor的开销明显比Thread大;
其他优化,请参考文章:
android性能优化之布局优化
android性能优化之内存优化