Android开发: 关于性能需要考虑的
刚做Android开发时,只管完成任务,将需求完成,以能完成一款界面酷炫的app为自豪。然而,随着代码量的增加,越来越意识到,一款成功的移动端产品,光有酷炫的外衣还不够,还需要在各方面都优秀。
试想,拿着一款app,第一眼看去,页面静态效果完美,但试着去操作,点击按钮半天不见反馈,滑动时伴着卡顿效果,甚至时不时弹出个“应用程序无响应”,用户有何感想;又或者,装上app后,原本充一次电可以用一天,现在半天就没电了,偶尔放在口袋里手机感觉会发烫。其实这些,都是一些看得见或看不见的性能问题,作为一名合格的开发者,我们应该尽量去解决。
性能优化,我认为主要从这几个方面考虑(个人观点,不对或者遗漏的欢迎指出和补充):
1、适当的UI布局
2、高效的代码/语法,合理的数据结构和算法
3、减少不必要的内存开销,降低垃圾回收频率
4、合理使用线程、缓存、预加载等解决性能瓶颈
5、其它优化(网络、图片、资源等 )
1、 适当的UI布局,自定义view
①.布局优化
使用RelativeLayout替代多次嵌套的LinearLayout;使用include、merge、ViewStub标签;减少冗余的层级嵌套及复杂布局;该使用GONE的地方不要使用INVISIBLE;使用weight时,设置width或height为0dp,减少运算;减少非必要的layout背景设置;利用lint进行布局优化,减少非必要元素。
②.自定义view
draw、measure、layout中尽量不做耗时操作;使用一些自定义itemView替换复杂嵌套的item,减少measure和layout次数;使用clipRect()确认绘制区域,减少不必要的绘制;文本绘制时,使用StaticLayout进行文本换行,而不必自己进行计算;绘制bitmap时如果有需要先压缩;
③.使用RecyclerView
使用RecyclerView替换listview,或scrollview,listview,gridview等的嵌套布局;不但可以减少层级,而且RecyclerView在增删item时更有效率,不需要刷新所有item
2、 高效的代码/语法 ,合理的数据结构和算法
可以肯定的是,这一条是所有程序员都希望做到的,也是任何阶段程序员都有能力去做的,而更加可以肯定的是,绝大多数程序员(包括我)都做得不够。包含了以下几点(想到哪写到哪,可能有点乱):
①.优先使用增强型for循环(forEach)
在做循环操作时,优先使用forEach(内部实现是iterator,效率与使用iterator相差不大,且代码简洁易于理解,缺点是无法进行remove操作,有remove操作可以直接使用iterator),ps:ArrayList除外,因为其使用数组作为存储结构,get操作非常高效,使用for循环的遍历效率比forEach高
②.运算操作使用移位,合理使用浮点型,少使用除法(其实这对于大部分app的性能而言只是九牛一毛,但使用到的地方较多,所以列出来讲一下)
在Android上,整型处理速度高于浮点型两倍以上。使用移位运算符也是考虑处理速度,理论上x>>2 运算速度是 x*2的2倍,乘法运算效率也优于除法
③.让curson的打开/关闭操作更合理,io流及时关闭
curson的打开及关闭是比较耗时的操作,在确保使用完毕后再关闭。io流用完及时关闭,不然会影响到文件被其他程序使用,出现不可控的异常情况。
④.context的使用
周期长的context引用使用application context,不要直接使用Activity,以免造成内存泄漏。activity实例确保仅在Activity生命周期内引用。切记避免静态context。
⑤.合理使用SoftRefrerence和WeakReference
确保内存不足时能得到释放。如Bitmap等...
⑥.使用webview需要销毁
在Activity/Fragment生命周期结束时调用webview.destory()
⑦.String/StringBuilder/StringBuffer合理使用
纯字符串拼接时(如“I” + " am "+"Thinkin Liu"),String更高效,因为在编译时,就已经将其拼接成一个字符串。而在不需要考虑线程安全的情况下,StringBuilder比StringBuffer及String更高效。
⑧.ArrayList,LinkedList等数据结构合理使用
在顺序增加add(Object)和查找get操作比较多时,使用ArrayList更有优势
而在无序的增删中,使用LikedList更占优势
⑨.使用SparseArray替代HashMap<Integer, Object>
SparseArray内存分配优化、使用binarySearch等让其更有效率,相应的有SparseBooleanArray,SparseIntArray等
⑩.序列化Serializable和Parcelable
在内存间数据传输时推荐使用Parcelable,可减少大量的临时变量,防止GC频繁调用;读写数据时,Parelable是在内存中直接读写,而Sericalizable是通过使用IO流的形式将数据读写入在硬盘上
3、减少不必要的内存开销,降低垃圾回收频率
其实在上面(二)已经涉及到了内存开销和减少GC,下面也会涉及到(四)。但这点是内存性能问题的本质,单独提下:
①.避免非必要对象的创建
对象的频繁创建和销毁,能使内存的使用率过高,出现内存抖动现象,进而导致GC频繁。
②.避免频繁代码调用System.gc()
4、合理使用线程、缓存、预加载、延时加载等解决性能瓶颈
①.做耗时操作时,将其放入线程中
如文件读写、数据库操作、网络访问、耗时计算等,不要在UI线程中进行,以免影响到UI的刷新
②.使用线程池
使用线程池,而不是单独的开启线程,线程池可以更便利的管理线程,同时还包含复用机制
③.合理的在子线程中sleep()
子线程需要进行耗时长的操作时(如文件上传),合理的每隔一段时间sleep(10),将cpu让给其他线程(目标是UI线程),页面刷新会更顺畅
④.合理的利用缓存
如listview中复用convertView,使用ViewHolder;图片的三级缓存机制;网络请求的数据缓存...这些缓存可以让下一次用到时加载速度更快。
⑤.合理的预加载和延时加载
如图片浏览时,将前后图预加载,解决滑动切换后的黑屏问题;列表中的头像延时加载处理,可以让滑动更顺畅。
5、其它优化(网络、图片、资源等 )
①.网络优化
开启长连接(减少tcp三次握手及四次挥手,缺点是资源占用);使用缓存(根据版本号判断是否需要返回新的数据,减少数据传输);列表页预加载;将多个请求合并;区分不同网络(wifi/4G高并发,2G优先低并发,优先核心请求);设置TimeOut;数据进行压缩;使用ip替代域名进行请求(省去dns开销);选择高效的网络框架(如okhttp)
②.图片/资源优化
使用bitmap时压缩加载;加载大图时候考虑使用BitmapRegionDecoder;使用完bitmap及时recycle();使用.9图;使用矢量图VectorDrawable;
③.了解并使用库函数
Java标准库和Android Framework中包含了大量的库函数,不少函数采用native实现,通常情况下比用Java实现同样功能的效率要高。
④.工具的使用
利用Android各种工具进行内存,cpu,电量等分析,如何使用网上不少,这里不多说了
ps:先写这么多了,感觉有点乱,其实主要涉及到的就是cpu/gpu(计算、处理、渲染等),内存(内存泄漏,内存抖动,内存溢出)的优化。
以上只是临时想到的一些性能优化点,有不对的请指出,有缺少的也麻烦补充下,多谢!
转自我的简书
Android开发: 关于性能需要考虑的的更多相关文章
- Android开发——布局性能优化的一些技巧(一)
0. 前言 上一篇我们分析了为什么LinearLayout会比RelativeLayout性能更高,意义在于分析了这两种布局的实现源码,算是对一个小结论的证明过程,但是对布局性能的优化效果,对这两种布 ...
- Android开发——布局性能优化的一些技巧(二)
, 0, drawable.getMinimumWidth(),dra.getMinimumHeight()); tv.setCompoundDrawables(null, null, drawabl ...
- (转) Android开发性能优化简介
作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...
- [素材资源] Android开发性能优化简介(非常不错的)
转自(http://www.starming.com/index.php?action=plugin&v=wave&tpl=union&ac=viewgrouppost& ...
- Android 开发性能优化之SparseArray(一)
多数Android开发者都知道在Android中可以使用HashMap来映射一种对应关系,在java开发中HashMap也算是一种很重要的数据存储结构.然后很多人在Android开发中多数都会用Has ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 《android开发艺术探索》读书笔记(十五)--Android性能优化
接上篇<android开发艺术探索>读书笔记(十四)--JNI和NDK编程 No1: 如果<include>制定了这个id属性,同时被包含的布局文件的根元素也制定了id属性,那 ...
- Android开发——LinearLayout和RelativeLayout的性能对比
0. 前言 我们都知道新建一个Android项目自动生成的Xml布局文件的根节点默认是RelativeLayout,这不是IDE默认设置,而是由android-sdk\tools\templates\ ...
- Android开发笔记——ListView模块、缓存及性能
ListView是Android开发中最常用的组件之一.本文将重点说明如何正确使用ListView,以及使用过程中可能遇到的问题. ListView开发模块 图片缓存 可能遇到的问题 一.ListVi ...
随机推荐
- TensorFlow-GPU环境配置之一——安装Ubuntu双系统
本机已经安装过Windows系统,准备安装Ubuntu双系统进行TensorFlow相关工作,需要在windows中将磁盘分出一定空间供Ubuntu使用 1.首先下载Ubuntu17.04版本ISO ...
- [Jexus系列] 一、安装并运行 Jexus
注意,本教程使用的jexus版本为5.8.3专业版,操作系统为 Ubunutu 16.04 64位 一.创建默认站点 不熟悉vim的可以看这个: vim超简单入门教程 sudo mkdir -p /v ...
- Centos系统备份
使用root用户切换到根目录 然后,使用下面的命令备份完整的系统: tar cvpzf backup.tgz / --exclude=/proc --exclude=/lost+found --exc ...
- PowerDesinger15设置字体大小
使用PowerDesigner时,它默认table的字体大小颜色等很难看: 假设通过 Symbol ---> Format进行设置.仅仅能对选中的最改动,新建的Table无效. 能够通过例如以下 ...
- [Javascript] Flattening nested arrays: a little exercise in functional refactoring
In this lesson we write an imperative function to flatten nested arrays, and then use the popular ma ...
- java 代理模式具体解释
java 动态代理(JDK和cglib) 设计模式这东东每次看到就明确可过段时间又不能非常流利的说出来.今天就用具体的比喻和实例来加深自己的理解(小弟水平不高有不正确的地方希望大家能指出来). (1) ...
- Wordpress 建站(一)
去年在美国的justhost上买了两个域名(shanyexuanyu.com 和 chenjinyu.net.shanyexuanyu.com是给一位马来西亚的佛教徒朋友做的站点. 她镜头下佛教的文 ...
- SQLServer IP不能登录问题解决
最近项目项目需要,要在windows2008R2服务器上部署项目,可是客户那边服务器上SqlServer也没有安装,一切都要自己解决,所以我就找了个2008的版本,进行安装,安装过程没有遇到什么问题, ...
- 【bzoj1042】[HAOI2008]硬币购物
首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案. 为了避免重复的方案被转移,所以我们以硬币种类为第一层循环,这样阶段性的增加硬币. 一定要注意这个第一层循环要 ...
- P2465 [SDOI2008]山贼集团 dp
这个题是一道树形dp+状压dp二合一,先预处理每种组合会有什么额外的费用,然后在树上dp就行了. 题干: 题目描述 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两 ...