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

来源:互联网 发布:杭州java应届生招聘 编辑:程序博客网 时间:2024/06/05 16:42

之前的文章从理论上介绍了Android高性能编码的几个优化的方向,下面我们从实战的角度讲述如何优化

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

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

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


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

04-25 14:15:10.803 7202-7202/com.js.test E/Test: app start at 149310091080204-25 14:15:12.200 7202-7202/com.js.test E/Test: Launch app cost time 139804-25 14:15:12.200 7202-7202/com.js.test E/Test: Enter main fragment cost time 139804-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 149310150758004-25 14:25:08.594 22575-22575/com.js.test E/Test: Launch app cost time 101404-25 14:25:08.594 22575-22575/com.js.test E/Test: Enter main fragment cost time 101404-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 149310321150404-25 14:53:32.281 27039-27039/com.js.test E/Test: Launch app cost time 77704-25 14:53:32.281 27039-27039/com.js.test E/Test: Enter main fragment cost time 77704-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 149310439927604-25 15:13:20.063 24571-24571/com.js.test E/Test: Launch app cost time 78704-25 15:13:20.063 24571-24571/com.js.test E/Test: Enter main fragment cost time 78704-25 15:13:20.211 24571-24571/com.js.test E/Test: Show Cache data cost time 93504-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

1 0
原创粉丝点击