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 ...
随机推荐
- 我的arcgis培训照片9
来自:http://www.cioiot.com/successview-547-1.html
- SD卡 驱动层测速
init_timer(&timer1); timer1.function = test_time; timer1.data = ; timer1.expires = jiffies + mse ...
- sqlit中使用到的查询语句
近期使用sqlite查询比較多,包含连表查询等. 记录一下.以免忘记! 1.先依据时间排序后选择前十条: select * from MyBill order by createTime desc ...
- VMware实用技巧
1.VM快照管理 这个功能实在太常用,不用我多废话.这里只是提醒一下还没有用过快照的同学,赶紧的给自己的VM保存点快照吧,这样VM里的系统出了问题或是有其它需要很容易让你还原到原来的某个点,这功能可比 ...
- java入门之——对象转型
对象的类型转换是我们在编程的时候常常会遇到的,java平台也是如此.比方一些基本类型的数据转型和复合数据的转换. 举例 java语言中主要分为向上转型和向下转型,怎样来了解和掌握这两者转型的关系呢?首 ...
- Androidbuttonshape形状资源码实现
1.项目Src下创建drawable 看文档Develop/API Guides/App Resources/Drawable/Shape Drawable 单词:corners : 角 ; gr ...
- vue中slot的笔记
一言以蔽之:本来写在子组件里边的内容默认是不显示的,如果想相对于子组件在哪里进行显示,则使用slot标签代表占位符,代替那部分内容,是行间元素还是块级元素取决于原先的那个标签. 参考的连接是:http ...
- 记录一次node中台转发表单上传文件到后台过程
首发掘金 记录一次node中台转发表单上传文件到后台过程 本篇跟掘金为同一个作者leung 公司几个项目都是三层架构模式即前台,中台(中间层),后台.前台微信端公众号使用vue框架,后台管理前端使 ...
- 12.解决CCScale9Sprite或者CCControlButton无法使用的问题。
问题: 使用CCScale9Sprite或者CCControlButton等控件的时候,会出现无法识别的情况. 解决方式: 1.include对应的头部,即#include "cocos-e ...
- android学习一(了解android)
声明:android学习文件中面的全部内容为都是整理来自第一行代码Android.在接下来的文章里我就不在进行反复的声明. 想看原版的能够买书看看.或者去作者的博客http://blog.csdn.n ...