在开发Android应用程序的过程中,经常会遇到App首页的加载时间慢,需要需要进行性能优化的问题。那么如何知道首页Activity的加载时间呢 ?
1. 当我们打开一个Activity的时候,log会打印一串log如下:
I/ActivityManager﹕ Displayed xxx.xxx.xxx/TestActivity: +1s272ms (total +3s843ms)
- 第一个时间表示系统接受到打开的intent到HomeActivity界面显示出来的时间1.272秒。
- 第二个时间特殊情况下才会有。例如这种调用流程:A->B(在onCreate立刻finish掉自己,直接跳转到C)->C(TestActivity),它包含了B页面onCreate处理以及finish的时间。这个时间如果过长,会导致用户点击跳转后,页面还停留在原来界面,延迟一段时间再跳转。这种体验很差,用户会觉得卡顿并容易点击多次。很多应用程序的入口页面,都设计成这种情况的跳转。
在此我们只讨论第一个时间,在这个时间内系统做了以下事情:ActivityManager做一些task相关的处理 -> 应用内创建Activity实例 -> Activity的onCreate->Activity的onResume->布局的初始化->首次绘制的一些东西,这个流程是指一个Activity在一个task初次创建的情况。如果是clearTop等流程,可能还涉及其他Activity的finish,自己onNewIntent等流程。
2. 优化这个时间的主要针对以下几点:
- 降低onCreate, onResume里的处理耗时
- 降低界面没显示出来时的主线程占用
- 避免在主线程调用阻塞方法
- 简化布局,减少资源加载和布局计算的时间
除了上述常见的一些优化点之外,还有其它一些处理方法:
- IO操作:包括File,AssetManager,网络,数据库访问,都进行异步访问处理
- SharePreference:用apply代替commit,apply会把文件写的部分用异步线程处理
- setContentView:这里面会处理各种类创建和资源加载。这里是最难处理的,而且耗时通常很高,最好是调整资源加载流程,比如先显示页面框架,再渐变加载内容。这里介绍一个特殊案例:在App欢迎页显示的时候预加载首页资源,然后跳转到首页
View preLoadMainHome=null;
protected void preLoadResource(){
if (preLoadMainHome == null) {
preLoadMainHome=View.inflate(this,R.layout.main_home,null);
}
}
这里的R.layout.main_home就是首页的布局文件,这里只是实例化它,不做任何事情,虽然我们后面用的不是这个实例,但是ResourceManager会把这个layout需要的drawable都加进内存。通过这一步处理,当跳转到首页时setContentView的加载时间就会大大降低。不过这个方法有诸多限制:
(1). 首先它并不是不耗时间的,需要一个空闲时间去初始化它,如果有些应用的欢迎页面是静态页面,就很适合这种方法
(2). ResourceManager里的drawable缓存是weakReference的,GC会回收它,这里把它声明为成员变量就是为了减少回收的可能
(3). 这样会导致瞬时内存很高,虽然页面跳转之后会降下来,但如果当时太高的话,有可能OutOfMemery
3. 若要想更加详细具体地分析每个View的加载时间,需要使用一些专门性能分析工具:
4. 下面是我们总结的Android 性能优化的几个要点: