刚做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开发: 关于性能需要考虑的的更多相关文章

  1. Android开发——布局性能优化的一些技巧(一)

    0. 前言 上一篇我们分析了为什么LinearLayout会比RelativeLayout性能更高,意义在于分析了这两种布局的实现源码,算是对一个小结论的证明过程,但是对布局性能的优化效果,对这两种布 ...

  2. Android开发——布局性能优化的一些技巧(二)

    , 0, drawable.getMinimumWidth(),dra.getMinimumHeight()); tv.setCompoundDrawables(null, null, drawabl ...

  3. (转) Android开发性能优化简介

    作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...

  4. [素材资源] Android开发性能优化简介(非常不错的)

    转自(http://www.starming.com/index.php?action=plugin&v=wave&tpl=union&ac=viewgrouppost& ...

  5. Android 开发性能优化之SparseArray(一)

    多数Android开发者都知道在Android中可以使用HashMap来映射一种对应关系,在java开发中HashMap也算是一种很重要的数据存储结构.然后很多人在Android开发中多数都会用Has ...

  6. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  7. 《android开发艺术探索》读书笔记(十五)--Android性能优化

    接上篇<android开发艺术探索>读书笔记(十四)--JNI和NDK编程 No1: 如果<include>制定了这个id属性,同时被包含的布局文件的根元素也制定了id属性,那 ...

  8. Android开发——LinearLayout和RelativeLayout的性能对比

    0. 前言 我们都知道新建一个Android项目自动生成的Xml布局文件的根节点默认是RelativeLayout,这不是IDE默认设置,而是由android-sdk\tools\templates\ ...

  9. Android开发笔记——ListView模块、缓存及性能

    ListView是Android开发中最常用的组件之一.本文将重点说明如何正确使用ListView,以及使用过程中可能遇到的问题. ListView开发模块 图片缓存 可能遇到的问题 一.ListVi ...

随机推荐

  1. linux 用 rsync 快速删除大量小文件

    假设我们在目录 /tmp/to_delete 下有很多小文件 a1 a2 a3 f1 f2 f3 现在我们想快速的删除f 开头的文件. 如果文件量大,用rm 可能会失败,而且会很慢, 所以用rsync ...

  2. Java 代理模式和装饰者模式的区别

    装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案:代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用: 装饰模式应该为所装饰的对象增强功能:代理模式对代理的 ...

  3. jmeter的Classpath即类或者jar包的搜索路径设置

    对于master-slave模式,插件和依赖都需要放到slave上才能生效,并且需要重启slave使插件生效 查看配置文件:apache-jmeter-3.1/bin/jmeter.propertie ...

  4. no matching function transform?

    http://stackoverflow.com/questions/19876746/stdtolower-and-visual-studio-2013 http://forums.codeguru ...

  5. webpack-输出

    输出(Output) 配置 output 选项可以控制 webpack 如何向硬盘写入编译文件. 注意,即使可以存在多个入口起点,但只指定一个输出配置. 用法(Usage) 在 webpack 中配置 ...

  6. Android框架之高速开发框架xUtil

    做Android开发我们通常是从原生态的開始,就是调用默认那些Android代码来开发我们的应用,可是到了一定程度,我们就想着怎么来高速开发我们的应用.这个时候我们就要着手来研究框架了. 以下介绍一个 ...

  7. 一条SQL语句面试题:求选修所有课程的学生

    前几天求职面试,有一道SQL题:给出三个表:学生.课程.成绩,求选修了所有课程的学生. 一道看似很简单的问题,把我难住了,我改了又改,涂涂画画,抓耳挠腮,因为试卷没有多少空白位置了,最后只好放弃.心情 ...

  8. mysql_connect 等待时间长,修改连接地址为127.0.0.1即可

    程序搬家后,运行非常慢分析流程: 1.外网的等待时间太长 2.内容等待时间也很长 3.断点查到仅仅一句 mysql_connect ("localhost",***,***)就要1 ...

  9. oracle导入dmp文件时出现异常

    oracle导入dmp文件时出现错误 今天在给oracle导入dmp文件时老是出现错误,无论是命令行或PL/SQL,错误截图如下: 经查是导入用户的权限不足,导入用户并没有DBA权限,而导出的dmp文 ...

  10. 别再问什么是Java内存模型了,看这里!

    网上有很多关于Java内存模型的文章,在<深入理解Java虚拟机>和<Java并发编程的艺术>等书中也都有关于这个知识点的介绍.但是,很多人读完之后还是搞不清楚,甚至有的人说自 ...