性能优化

作者: Jimmy5Zhang | 来源:发表于2017-02-12 13:28 被阅读93次

    1、应用卡顿的原理,以及针对界面切换卡顿和屏幕滑动卡顿提出典型的解决思路

    卡顿原理:

    1)大多数手机的屏幕刷新频率是60hz,如果在1000/60=16.67ms内没有办法把这一帧的任务执行完毕,就会发生丢帧的现象。丢帧越多,用户感受到的卡顿情况就越严重。

    android手机屏幕绘制

    2)渲染操作通常依赖于两个核心组件:CPU与GPU。CPU负责包括Measure,Layout,Record,Execute的计算操作,GPU负责Rasterization(栅格化)操作。CPU通常存在的问题的原因是存在非必需的视图组件,它不仅仅会带来重复的计算操作,而且还会占用额外的GPU资源。

    CPU、GPU工作原理

    3)针对原理来作出解释如何优化

    3.1、减少视图的层级结构

    3.2、移除Window默认的background

    3.3、移除XML布局文件中非必需的background

    3.4、按需显示占位背景图片

    3.5、优化自定义View的ondraw方法

    3.6、ListView滑动取消图片加载

    3.7、ListView采用ViewHolder

    2、android中如何优化内存,针对项目中说出几种内存优化方案

    Android Studio中的Memory Monitor可以很好的帮助我们查看程序的内存使用情况。

    Memory Monitor内存分析

    1) 珍惜Services资源

    当你启动一个service,系统会倾向为了保留这个service而一直保留service所在的进程。这使得进程的运行代价很高,因为系统没有办法把service所占用的RAM空间腾出来让给其他组件,另外service还不能被paged out。这减少了系统能够存放到LRU缓存当中的进程数量,它会影响app之间的切换效率。它甚至会导致系统内存使用不稳定,从而无法继续保持住所有目前正在运行的service。

    限制你的service的最好办法是使用IntentService, 它会在处理完交代给它的intent任务之后尽快结束自己

    2) 避免bitmaps的浪费

    当你加载一个bitmap时,仅仅需要保留适配当前屏幕设备分辨率的数据即可,如果原图高于你的设备分辨率,需要做缩小的动作。请记住,增加bitmap的尺寸会对内存呈现出2次方的增加,因为X与Y都在增加。

    3) 使用优化的数据容器

    利用Android Framework里面优化过的容器类,例如SparseArray,SparseBooleanArray, 与LongSparseArray。 通常的HashMap的实现方式更加消耗内存,因为它需要一个额外的实例对象来记录Mapping操作。另外,SparseArray更加高效在于他们避免了对key与value的autobox自动装箱,并且避免了装箱后的解箱。

    4) 请注意内存开销

    对你所使用的语言与库的成本与开销有所了解,从开始到结束,在设计你的app时谨记这些信息。通常,表面上看起来无关痛痒(innocuous)的事情也许实际上会导致大量的开销。例如:

    Enums的内存消耗通常是static constants的2倍。你应该尽量避免在Android上使用enums。

    在Java中的每一个类(包括匿名内部类)都会使用大概500 bytes。

    每一个类的实例花销是12-16 bytes。

    往HashMap添加一个entry需要额一个额外占用的32 bytes的entry对象。

    5) 谨慎使用第三方libraries

    不要陷入为了1个或者2个功能而导入整个library的陷阱。如果没有一个合适的库与你的需求相吻合,你应该考虑自己去实现,而不是导入一个大而全的解决方案

    6)使用ProGuard来剔除不需要的代码

    7)避免在内部调用Getters/Setters方法

    在Android上这个技巧就不再是那么的受推崇了,因为字段搜寻要比方法调用效率高得多,我们直接访问某个字段可能要比通过getters方法来去访问这个字段快3到7倍

    8)使用增强型for循环语法

    9)避免创建不必要的对象

    因此请尽量避免创建不必要的对象,有下面一些例子来说明这个问题:

    你需要返回一个String对象,并且你知道它最终会需要连接到一个StringBuffer,请修改你的函数实现方式,避免直接进行连接操作,应该采用创建一个临时对象来做字符串的拼接这个操作。

    当从已经存在的数据集中抽取出String的时候,尝试返回原数据的substring对象,而不是创建一个重复的对象。使用substring的方式,你将会得到一个新的String对象,但是这个string对象是和原string共享内部char[]空间的。

    一组int数据要比一组Integer对象要好很多。可以得知,两组一维数组要比一个二维数组更加的有效率。同样的,这个道理可以推广至其他原始数据类型。

    如果你需要实现一个数组用来存放(Foo,Bar)的对象,记住使用Foo[]与Bar[]要比(Foo,Bar)好很多。(例外的是,为了某些好的API的设计,可以适当做一些妥协。但是在自己的代码内部,你应该多多使用分解后的容易)。

    10)常量声明为Static Final

    11)避免使用float类型

    Android系统中float类型的数据存取速度是int类型的一半,尽量优先采用int类型。

    就速度而言,现代硬件上,float 和 double 的速度是一样的。空间而言,double 是两倍float的大小。在空间不是问题的情况下,你应该使用 double 。

    相关文章

      网友评论

        本文标题:性能优化

        本文链接:https://www.haomeiwen.com/subject/igdaittx.html