一直没系统性的总结,自己感觉这块的东西半生不生,说又不能系统性的说出来,毫无实战毫无意义。有时感觉自己很废,不管怎样,生活还的继续,还的面对废物的自己
启动优化的目的是为了提升用户打开App时候的第一体验,程序开发者都应该致力于将App的用户体验想尽办法提升到极致。
启动时间统计
启动耗时衡量的标准,市面上一般主流的App的启动耗时在1200ms左右,秒开的感觉。
启动优化,优化的是冷启动:从应用进程开启到第一个页面呈现在用户眼前这段时间,成为启动耗时的窗口期。优化的目标就是缩短这段是时间。
启动耗时统计方法,这里推荐两种:
- 在Application的attachBaseContext方法中埋下启动的时间记录,在Activity的windowFocusChanged方法中埋下启动结束的时间,因为在windowFocusChanged方法中第一个回调是第一帧数据的回调。实际上在第一帧数据渲染的时候还会耗费一定的时间,可以在view绘制完成的回调里边埋下启动完成的时间标记,才是更合理的。反正只要是缩短了启动时间,怎么记录,有点误差其实问题不大,只要达到启动的秒开体验就好。
直接在onWindowFocusChanged中统计启动结束时间好了。
-
杀掉进程启动app,在logcat窗口过滤Displayed
image.png
上图记录了市面上主流的App的启动时间,支付宝、淘宝、京东、美团等,大多都在1200ms左右,QQ特别快。
另外一种,adb命令统计App启动时间
adb shell am start -W packagename/首屏Activity(这里需要使用全类名)
ThisTime:最后一个Activity启动耗时
TotalTime:所有Activity启动耗时(这里ThisTime和TotalTime值是一致的,因为我的Demo中只有一个MainActivity)
WaitTime:AMS启动Activity的总耗时,对于一个通用的app(包含SplashActivity),ThisTime肯定是小于TotalTime的,即:
ThisTime < TotalTime < WaitTime
总结:这种方式线下使用方便,可以使用这种方式测量竞品为竞品分析提供需要的数据,不能带到线上,并且测量出来的时间也是一个非严谨精确的时间。
优化手段
-
视觉优化,给启动页Activity设置Theme,在Activity启动的时候会创建一个背景全白的window,可以通过设置Theme营造一种秒开的视觉差,提升视觉效果。
-
提前初始化,在应用启动时候需要立即初始化的库,以及第三方库可以放置在ContentProvider的onCreate方法里边初始化,第三方ContentProvider合并可以使用StartUp。ContentProvider的onCreate方法会在ApplicationCreate方法之前执行。
-
异步初始化,在应用启动后不久需要使用的库的初始化可以放在Application的onCreate方法中加载线程池进行异步初始化。例如:在首页MainActivity中需要使用的库,就可以使用A异步初始化。
-
启动页优化,Application和LaunchActivity中不要做任何的同步阻塞任务,阻塞任务全部放置在自线程中异步执行。启动页LaunchActivity的布局不要使用XML静态布局的方式,直接使用new 布局对象的方式将View组建好,添加给decorView,这样节省了XML加载解析的时间。同时创建的自线程应该主动设置优先级,不然会默认继承父Thread的优先级,应用启动的时候默认是主线程,子线程会抢占主线的CUP执行资源。
当然,也不是说不能在主线程执行任务,可以在主线程空闲下来执行任务,利用handler的IdleHandler监听主线程空闲
//IdleHandler分批处理并在系统空闲时执行
private MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() { //系统空闲时回调
}
};
- 延迟初始化,在应用启动之后不需要及时使用的库,可以在需要使用的页面进行初始化。
以上策略综合使用,就可以将绝大多数场景的Android启动时间做到1200ms左右。就是围绕减轻Application和LaunchActivity启动时候的任务压力,将压力分摊出去,避免出现启动的时候主线程拥塞。
可以参考我的这篇文章,Android应用启动优化实践
网友评论