Android提升进入界面的速度
应用除了有内存占用、内存泄露、内存抖动等看不见的性能问题外,还有很多看得见的性能问题,比如进入界面慢、点击反应慢、页面卡顿等等,这些看得见的体验问题会严重影响用户使用APP心情,但用户的情绪又无法通过异常采集、数据分析来发现,尽早优化APP的性能体验问题非常重要,会在一定程度上提升用户的留存率。
本文结合最近一段时间对项目中APP各界面进入速度的优化,总结一下进入界面慢的优化方案。
先从Activity的生命周期说起
从一个界面FirstActivity跳转到另外一个界面SecondActivity,两个Activity的生命周期流程是这样的:
应用必须在走完FirstActivity的onPause方法后才会跑SecondActivity的onCreate方法,FirstActivity的onStop和onDestory方法不会影响到进入SecondActivity的速度。如果我们要优化从FirstActivity跳转到SecondActivity的速度,需要从FristActivity的onPause和SecondActivity的onCreate、onStart和onResume方法入手。onStart方法通常干的事情比较少,页面之间跳转慢主要是因为在FirstActivity的onPause和SecondActivity的onCreate、onResume方法耗时导致,这个过程需要执行的操作主要有:
保存FirstActivity界面中的一些状态;
加载SecondActivity的布局;
初始化SecondActivity。
针对上面的分析我们可以从如下四个方面入手:
耗时任务异步处理;
布局文件优化;
不可见视图需要时加载;
应用内慎用多进程。
优化实践
耗时任务异步处理
除了Android明令禁止在UI线程中执行网络操作外,还有一些耗时的操作也不能在UI线程中执行,比如IO操作、耗时较长的逻辑操作(比如算法),在Android中可以通过如下几种方式来实现异步任务:
AsyncTask
Thread
Timer,TimerTask
Handler
如果是在执行异步任务后需要更新界面,优先考虑使用AsyncTask和Handler,它们提供了刷新UI的方案;如果是定时任务可以考虑使用Handler和Timer,TimerTask;如果是使用Thread和Timer,TimerTask,更新UI时可以通过执行当前Activity的runOnUiThread方法实现更新UI操作。
布局文件优化 ViewStub
在优化过程中发现有的界面光是加载布局就需要500ms左右,再加上界面的初始化和上一个界面的状态保存操作,页面跳转时会有严重的迟滞感,对于布局文件的优化网上有很多有价值的文章,最重要的两条是:
布局文件不要嵌套太深;
对于不需要进入界面就需要显示的视图,强烈建议使用ViewStub。
布局文件嵌套太深标示着需要更多次的布局、测量和绘制,会导致耗时更多,这个可以使用android自带的“hierarchyviewer”查看,边优化边看效果;但有时候即使布局足够扁平,加载布局文件时还是会比较耗时,因为布局文件中的视图太多了,此时对于不需要进入界面就需要显示的视图,可以使用ViewStub来延迟加载,比如加载的进度条、特定状态下出现的倒计时和动画等,ViewStub的使用方式如下:
/**
* 在需要使用下载进度条的地方调用该方法加载下载进度条的布局
*/
private void initDownloadProgress() {
if(null == mDownloadViewStub){
mDownloadViewStub = (ViewStub)findViewById(R.id.downProgressViewStubId);
View view = mDownloadViewStub.inflate();
mDownloadProgressLayout = (RelativeLayout) view.findViewById(R.id.progressBackLayoutId);
mDownLoadProgressBar = (ArrowProgressBar) view.findViewById(R.id.arrowProgressBarId);
mDownloadProgressLayout.setVisibility(View.GONE);
mDownloadProgressLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
}
不可见视图需要时加载
除了布局文件的优化外,代码中不需要立即显示的视图和动画都做成延迟加载,比如AnimationDrawable、TypedArray数组、Typeface、addView等,值得一提的是,初始化AnimationDrawable、TypedArray数组和Typeface会很耗时,并且AnimationDrawable特别耗内存,如果不是进入界面就需要使用,强烈建议在需要使用的地方再初始化,分开初始化可以大大减小页面初始化的耗时。
应用内慎用多进程
从FirstActivity跳转到SecondActivity,如果这两个界面不属于同一个进程,首次跳转的时候会创建一个新的进程,创建进程是比较耗时的,比跳转到同一进程内的新页面耗时更多,如果不是必须要在应用内使用多进程,强烈建议不要在应用内使用多进程。
总结
性能优化是一个持续的过程,界面跳转效率只是一个性能指标,更快地跳转对于用户来说有着更好地体验,优化界面跳转速度的步骤如下:
打印执行每一段代码执行需要的时间;
找到耗时较多的代码段,可能是setContentView,也有可能是在UI线程中的其它耗时操作;
根据耗时的代码段找解决办法;
优化后运行看效果。
特别说明:
初始化AnimationDrawable、TypedArray数组和Typeface会很耗时,并且AnimationDrawable特别耗内存,一定要注意他们的初始化时机;
不要迷信网上的一些优化技巧,一定要结合亲身实践,看数据说话;
只要认真分析,很多地方都会有优化空间,将优化的经验总结出来,并运用到后续的开发中;
优化APP的性能问题在一定程度上能够提高用户的留存率,是一件很有价值的事情。
Android提升进入界面的速度的更多相关文章
- 【Android优化篇】提升Activity加载速度的方法
文章转自:http://www.jianshu.com/p/2007ca0290d3 作者: CoderFan 前言 这个也是我面试遇到的问题,当时只回答了一种情况,异步加载数据,没想到别的方式,回来 ...
- Android提升Gradle编译速度或减少Gradle编译时间.md
目录 Android如何提升Gradle编译速度或减少Gradle编译时间 最终优化方案 优化效果比对 将所有项目源码,各种缓存临时目录都移动到高性能SSD磁盘上 gradle.properties ...
- 【转】实践最有效的提高Android Studio运行、编译速度方案
原文:https://blog.csdn.net/xwh_1230/article/details/60961723 实践最有效的提高Android Studio运行.编译速度方案 最有效提升Andr ...
- 如何提升ACTION_SIM_STATE_CHANGED的接收速度?
在Android中,BroadcastReceiver分动态注册和静态注册. 静态注册的一个优势就是:当你的BroadcastReceiver可以接受系统中 某个broadcast时,系统会自动启动你 ...
- 解决Android Graphical Layout 界面效果不显示
解决Android Graphical Layout 界面效果不显示 qq463431476
- Android之拨号界面图片风格,无信息默认显示界面修改
Android之拨号界面图片风格,无信息默认显示界面修改 点开Dialer app,出现拨号,联系人,收藏三个选项卡,也就是三个Fragment,在三个界面都没有信息的时候会显示一个时钟,联系人,收藏 ...
- Android实现入门界面布局
Android实现入门界面布局 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 代码实现 首先是常量的定义,安卓中固定字符串应该定义在常量中. stri ...
- Android的配置界面PreferenceActivity
我想大家对于android的系统配置界面应该不会陌生吧,即便陌生,那么下面的界面应该似曾相识吧,假若还是不认识,那么也没有关系,我们这一节主要就是介绍并讲解android 中系统配置界面的使用,相信大 ...
- 图解android开发在界面上显示图片
图解android开发在界面上显示图片<申明:转自百度> <原文章地址:http://jingyan.baidu.com/article/49711c6153a277fa441b7c ...
随机推荐
- linux源代码阅读笔记 八进制
c语言中,众所周知,以0x开头的数是16进制数.例如 0x8FFF 然而较少使用的是八进制数.它以0开头.例如 01234
- hdoj 1875 畅通工程再续
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1875 //9403289 2013-10-24 17:00:49 Accepted 1875 62M ...
- DP方程及意义
01背包 有N件物品和一个容量为V的背包.第i件物品的费用(即体积,下同)是w[i],价值是c[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路: 这是最基 ...
- lintcode : 二叉树的序列化和反序列化
题目 二叉树的序列化和反序列化 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制 ...
- lintcode:Binary Tree Postorder Traversal 二叉树的后序遍历
题目: 二叉树的后序遍历 给出一棵二叉树,返回其节点值的后序遍历. 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返回 [3,2,1] 挑战 你能使用非递归实现么? 解题: 递归程序 ...
- 核心思想:百度网盘怎么盈利(互联网的高速更新决定了:亏钱你还有点机会,放弃连门都进不了),战略预备队 good
百度做网盘很大程度就是为了防止别人依靠网盘做大和积累点技术储备.腾讯邮箱怎么赚钱?腾讯影音怎么赚钱?互联网的高速更新决定了,一些你看不起眼的软件很可能就会席卷整个市场,所以互联网大佬宁愿一些项目亏钱也 ...
- JavaScript DOM编程基础精华03(动态设置,层的操作,性能问题)
代码是否需要放置到onload中 //如果js代码需要操作页面上的元素,则将该代码放到onload里面. //因为当页面加载完毕之后页面上才会有相关的元素 //如果js代码中没有操作 ...
- Linux autoconf和automake使用
作为Linux下的程序开发人员,一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下,大家都是手工写一个简单Makefile,如果要想写出一个符合自由软件惯例的Mak ...
- Buffer数据结构和new IO的Memory-mapped files
一.Buffer类 java.nio.Buffer这个类是用来干什么的?有怎样的结构? "Core Java"中是这样定义的“A buffer is array of values ...
- SQL效率问题
关于in和or的效率对比:http://blog.chinaunix.net/uid-20639775-id-3416737.html 在没有索引的情况下,in的效率高 SQL语句效率:http:// ...