您的位置:首页 > 移动开发

[置顶] Android高性能编码实战:App启动优化

2017-04-25 15:36 495 查看
之前的文章从理论上介绍了Android高性能编码的几个优化的方向,下面我们从实战的角度讲述如何优化

Android高性能编码实战:App启动优化

Android高性能编码实战:网络框架优化

Android高性能编码实战:修复内存泄漏

App冷启动是很慢的,期间有大量的对象被创建,进程创建,分配内存,绘制界面,建立消息队列,各种第三方控件初始化等等,用户安装完APP,第一次启动,往往第一印象特别重要,启动迅速,显示流畅,就有很好的用户体验。

04-25 14:15:10.803 7202-7202/com.js.test E/Test: app start at 1493100910802
04-25 14:15:12.200 7202-7202/com.js.test E/Test: Launch app cost time 1398
04-25 14:15:12.200 7202-7202/com.js.test E/Test: Enter main fragment cost time 1398
04-25 14:15:13.049 7202-7202/com.js.test E/Test: Enter refresh data cost time 2247


优化前app启动到MainFragmentActivity onResume,共耗时1398毫秒

这个速度应该算不上迅速,而且界面显示出来会有将近的卡顿,去获取网络数据,期间用户是不能操作的。

这个APP有两个不好的体验

1.启动速度太慢,1.4秒才进入主界面

2.进入主界面空白,经过将近1秒刷新界面

首先,我们先来优化启动速度

在Application的onCreate方法中,有大量的初始化操作,

@Override
public void onCreate() {
super.onCreate();
startTime = System.currentTimeMillis();				//Test 起点
LogUtil.e("app start at "+startTime);
application = this;

initNetworkAPIConfig();								//Xutils 框架网络初始化
initImageLoader();									//ImageLoader初始化
ChatServiceHelper.getInstance().bindService(this);	//im通信service初始化
initUser();											//用户系统初始化,设置登出登录监听
initUmeng();										//Umeng统计初始化
}


第三方xutils、imageloader、umeng在这里初始化,还有账户监听和im消息service,它们的初始化占用了UI线程,违背了在生命周期里面做初始化操作的规定,但是它们必须在Activity启动前初始化完成,那么我们另起一个线程做这些初始化。

@Override
public void onCreate() {
super.onCreate();
startTime = System.currentTimeMillis();
LogUtil.e("app start at "+startTime);
application = this;

new Thread(new Runnable() {
@Override
public void run() {
initNetworkAPIConfig();
initImageLoader();
ChatServiceHelper.getInstance().bindService(application);
initUser();
initUmeng();
}
}).start();

}


优化以后的写法,我们来测试一下

04-25 14:25:07.581 22575-22575/com.js.test E/Test: app start at 1493101507580
04-25 14:25:08.594 22575-22575/com.js.test E/Test: Launch app cost time 1014
04-25 14:25:08.594 22575-22575/com.js.test E/Test: Enter main fragment cost time 1014
04-25 14:25:09.225 22575-22575/com.js.test E/Test: Enter refresh data cost time 1645


进入主界面的时间缩短了300-400毫秒。

第三方控件初始化放在MainActvity去做,不同进程所需的第三方控件不同,比如主进程需要ImageLoader、Xutils和Umeng,而im service只需要Xutils的数据库。

@Override
public void onCreate(Bundle savedInstanceState) {
new Thread(new Runnable() {
@Override
public void run() {
MyApplication.initImageLoader();
MyApplication.initNetworkAPIConfig();
MyApplication.initUmeng();
}
}).start();
super.onCreate(savedInstanceState);
}


我们先将Application的初始化方法设置为static静态,

在MainFragmentActivity的onCreate方法中进行第三方控件初始化,为防止出错,必须在网络接口返回数据前完成初始化,我们来测试一下耗时。

04-25 14:53:31.505 27039-27039/com.js.test E/Test: app start at 1493103211504
04-25 14:53:32.281 27039-27039/com.js.test E/Test: Launch app cost time 777
04-25 14:53:32.281 27039-27039/com.js.test E/Test: Enter main fragment cost time 777
04-25 14:53:32.973 27039-27039/com.js.test E/Test: Enter refresh data cost time 1469


启动时间缩短到了777毫秒,比最初的1498性能提升了将尽一倍。

下面我们来优化第二个问题,进入主界面页面空白的问题,需要等待1秒才能显示出数据

首先我们在系统空闲的时候,将最后一次的json保存到sd卡

SharePreferenceUtil.putString("cache", entity.toString());


在MainFragment的onResume方法中先将缓存数据显示出来

@Override
public void onResume() {
super.onResume();
long currentTime = System.currentTimeMillis();
LogUtil.e("Enter main fragment cost time "+(currentTime - MyApplication.startTime));

IndexEntity entity = JSONEntityUtil.JSONToEntity(IndexEntity.class, SharePreferenceUtil.getString("cache"));

updateView(entity);

currentTime = System.currentTimeMillis();
LogUtil.e("Show Cache data cost time "+(currentTime - MyApplication.startTime));
}
改造后的MainFragment onResume方法。

04-25 15:13:19.277 24571-24571/com.js.test E/Test: app start at 1493104399276
04-25 15:13:20.063 24571-24571/com.js.test E/Test: Launch app cost time 787
04-25 15:13:20.063 24571-24571/com.js.test E/Test: Enter main fragment cost time 787
04-25 15:13:20.211 24571-24571/com.js.test E/Test: Show Cache data cost time 935
04-25 15:13:20.880 24571-24571/com.js.test E/Test: Enter refresh data cost time 1604


787毫秒进入主界面,935毫秒显示出缓存界面,1604毫秒,刷新主界面。

上述优化可能极端情况下会有问题,需要经过反复测试,一定要在使用第三方控件前将其初始化。

我们针对两点改进APP启动体验,改进了四个地方

1.将某些模块和第三方控件的初始化放在了子线程去做

2.第三方控件延迟到使用时再初始化

3.缓存最后一次首页json数据,在APP启动时加载,防止出现空白页

4.多进程分开初始化,有些第三方控件不用的不必初始化

除了上述四点改进,

一般还有针对首页布局层次的优化,如果首页层次过多,OverDraw的红色区域就会很大,白白耗费性能,一般OverDraw为红色区域不宜大于1/4

另外Xutils 网络框架相对OKHttp慢不少,Json解析没有采用Gson或者fastJson这些性能最优的控件,若采用,启动速度将进一步提升。

参考文章

http://www.jianshu.com/p/f5514b1a826c
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: