这里根据网络上各位大神已经总结的知识内容做一个大汇总,作为记录,方便后续“温故知新”。

性能指标:

(1)使用流畅度:

   图片处理器每秒刷新的帧数(FPS),可用来指示页面是否平滑的渲染。高的帧率可以得到更流畅,更逼真的动画,不过帧率达到60fps以上,人眼主观感受到的差别就不大了。所以以60fps作为衡量标准,即要求每一帧刷新的时间小于16ms,这样才能保证滑动中平滑的流畅度。

(2)内存使用情况: 

  在android系统中,每个APP进程除了同其他进程共享(shared dirty)外,还独用私有内存(private dirty),通常我们使用PSS(=私有内存+比例分配共享内存)来衡量一个APP的内存开销。移动设备的内存资源是非常有限,为每个APP进程分配的私有内存也是有限制。一方面我们要合理的申请内存使用,以免导致频繁的GC影响性能和大对象申请发生内存溢出;另一方面,我们要及时释放内存,以免发生内存泄漏。

(3)电量使用情况:

  相对于PC来说,移动设备的电池电量是非常有限的,保持持久的续航能力尤为重要。另外,android的很多特性都比较耗电(如屏幕,GPS,sensor传感器,唤醒机制,CPU,连网等的使用),我们必须要慎重检查APP的电量使用,以免导致用户手机耗电发热,带来不良体验。

(4)流量使用情况:

  目前的网络类型包含2G\3G\4G\wifi,其中还有不同运营商的区分,我们在APP的使用中经常遇到大资源,重复请求,调用响应慢,调用失败等各种情况。在不同的网络类型之下,我们不仅要控制流量使用,还需要加快请求的响应。

原理以及优化技术要点

原理及相关知识介绍请参考google官方的教程:

android app性能优化大汇总(google官方Android性能优化典范 - 第1季)

android app性能优化大汇总(google官方Android性能优化典范 - 第2季)

android app性能优化大汇总(google官方Android性能优化典范 - 第3季)

具体优化方案:

android app性能优化大汇总(UI渲染性能优化)

android app性能优化大汇总(内存性能优化)

 代码编写风格细节对性能的影响:

1使用优化后的数据容器:

请使用 Andorid 框架中优化过的数据容器,例如 SparseArray,SparseBooleanArray 和 LongSparseArray。类似于 HashMap 这一类的容器的效率不是很高,因为在每个 Map 中对于每一次的存放数据,他都需要独立一个单独的 Entry 对象进行传芳。而 SparseArray 由于禁止系统自动封装键值对,因此他更加有效率。并且你不需要担心丢失掉原有信息。

2尽量避免使用枚举类型:

枚举与静态常量相比,通常会消耗两倍的内存资源。

3、避免创建不必要的对象:(特别是在onDraw类似的函数里)

创建太多的对象会造成性能低下,这谁都知道,可是为什么呢?首先分配内存本身需要时间,其次虚拟机运行时堆内存使用量是有上限的,当使用量到达一定程度时会触发垃圾回收,垃圾回收会使得线程甚至是整个进程暂停运行。可想而知,如果有对象频繁的创建和销毁,或者内存使用率很高,就会造成应用程序严重卡顿。(内存抖动)

4、合理使用static成员:

主要有三点需要掌握:
(1)如果一个方法不需要操作运行时的动态变量和方法,那么可以将方法设置为static的。
(2)常量字段要声明为“static final”,因为这样常量会被存放在dex文件的静态字段初始化器中被直接访问,否则在运行时需要通过编译时自动生成的一些函数来初始化。此规则只对基本类型和String类型有效。
(3)不要将视图控件声明为static,因为View对象会引用Activity对象,当Activity退出时其对象本身无法被销毁,会造成内存溢出。

5、 使用for-each循环:

增强的For循环(也被称为 for-each 循环)可以被用在实现了 Iterable 接口的 collections 以及数组上。使用collection的时候,Iterator (迭代器,译者注) 会被分配,用于for-each调用 hasNext() 和 next() 方法。使用ArrayList时,手写的计数式for循环会快3倍(不管有没有JIT),但是对于其他collection,增强的for-each循环写法会和迭代器写法的效率一样。

请比较下面三种循环的方法:

static class Foo {
int mSplat;
}
Foo[] mArray = ...
public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
} public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
} public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
  • zero()是最慢的,因为JIT没有办法对它进行优化。

  • one()稍微快些。

  • two() 在没有做JIT时是最快的,可是如果经过JIT之后,与方法one()是差不多一样快的。它使用了增强的循环方法for-each。

所以请尽量使用for-each的方法,但是对于ArrayList,请使用方法one()。

你还可以参考 Josh Bloch 的 《Effective Java》这本书的第46条

6、避免使用浮点类型:

经验之谈,所在Android设备中浮点型大概比整型数据处理速度慢两倍,以如果整型可以解决的问题就不要用浮点型。另外,一些处理器有硬件乘法但是没有除法,这种情况下除法和取模运算是用软件实现的。为了提高效率,在写运算式时可以考虑将一些除法操作直接改写为乘法实现,例如将“x / 2”改写为“x * 0.5”。

7、了解并使用库函数:

Java标准库和Android Framework中包含了大量高效且健壮的库函数,很多函数还采用了native实现,通常情况下比我们用Java实现同样功能的代码的效率要高很多。所以善于使用系统库函数可以节省开发时间,并且也不容易出错。

 8、避免依赖注入框架:

使用类似于 Guice 和 RoboGuice 的依赖注射框架,或许会使你的代码变得更加漂亮,因为他们能够减少你需要写的代码,并且为测试或者在其他条件改变的情况下,提供一种自适应的环境。但是,这些框架在初始化的时候会因为注释而消耗大量的工作在扫描你的代码上,这会让你的代码在进行内存映射的时候花费更多的资源。虽然这些内存能够被 Android 进行回收,但是等待整个分页被释放需要很长一段时间。

9、小心使用外部依赖包:

很多依赖包都不是专门为了移动环境或者移动客户端写的。如果你决定使用一个外部依赖包,你应该提前明白你需要为了将它移植到移动端而消耗花费大量的时间和工作量。请在使用外部依赖包得时候提前分析他的代码和内存占用

即使依赖包是为了 Android 而设计的,但是这也有潜伏的危险,因为每一个包都做着不同的工作。例如,有一个依赖包使用纳米级的 protobufs 但是别的包使用微米级的 protobufs.那么现在在你的应用中就有两套 protobuf 的标准了。这会在你记录数据,分析数据,加载图像,缓存,或者其他任何可能的情况下发生你不希望发生的事情。ProGuard 无法在这里帮助你,因为他们都是你所依赖包的底层实现,。当你使用从别的依赖包(他可能继承了很多的依赖包)里继承的 Activity 时,这个问题变得尤其严重,当你使用反射以及干别的事情的时候

请注意不要落入一个依赖包的陷阱,你不希望引入一大片你根本不会使用到的代码。如果你无法找到一种已经实现的逻辑来完全满足你的需求,那么你尽量创建一个自己的实现方式。

10、避免内部的Getters/Setters:

像C++等native language,通常使用getters(i = getCount())而不是直接访问变量(i =mCount)。这是编写C++的一种优秀习惯,而且通常也被其他面向对象的语言所采用,例如C#与Java,因为编译器通常会做inline访问,而且 你需要限制或者调试变量,你可以在任何时候在getter/setter里面添加代码。然而,在Android上,这是一个糟糕的写法。虚函数的调用比起直接访问变量要耗费更多。在面向对象编程中,将getter和setting暴露给公用接口是合理的,但在类内部应该仅仅使用域直接访问。在没有JIT(Just In Time Compiler)时,直接访问变量的速度是调用getter的3倍。有JIT时,直接访问变量的速度是通过getter访问的7倍。请注意,如果你使用 ProGuard , 你可以获得同样的效果,因为ProGuard可以为你inline accessors.

android app性能优化大汇总的更多相关文章

  1. android app性能优化大汇总(内存性能优化)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

  2. android app性能优化大汇总(UI渲染性能优化)

    UI性能测试 性能优化都需要有一个目标,UI的性能优化也是一样.你可能会觉得“我的app加载很快”很重要,但我们还需要了解终端用户的期望,是否可以去量化这些期望呢?我们可以从人机交互心理学的角度来考虑 ...

  3. android app性能优化大汇总(google官方Android性能优化典范 - 第1季)

    大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能.从设计师的角度,他们希望App能够有更多的动画,图片等时尚元素来实现流畅的用户体验.但是Android系统很有可能无法及时完成那些复杂的界 ...

  4. android app性能优化大汇总(google官方Android性能优化典范 - 第3季)

    (1)Fun with ArrayMaps 程序内存的管理是否合理高效对应用的性能有着很大的影响,有的时候对容器的使用不当也会导致内存管理效率低下.Android为移动操作系统特意编写了一些更加高效的 ...

  5. android app性能优化大汇总(google官方Android性能优化典范 - 第2季)

    Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...

  6. Android APP 性能优化的一些思考

    说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才 ...

  7. Android app 性能优化的思考--性能卡顿不好的原因在哪?

    说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才 ...

  8. 包建强的培训课程(9):Android App性能优化

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  9. fir.im Weekly - 如何进行 Android App 性能优化

    关于 Android App 的优化,@anly-jun 用 3 个月完成了这一系列文章,从 性能分析工具 到 ANR .Layout .消除卡顿 到 内存优化.内存分析工具大概十五六篇,并对此做一个 ...

随机推荐

  1. 手机布局rem的使用(rem)

    最后一堆代码是举例的全码. 一 直接<head>标签里套用以下,其他都不用 <script> document.documentElement.style.fontSize = ...

  2. oss 上传文件夹-cloud2-泽优软件

    说明: 1. 修复同时上传多个文件夹崩溃的问题. 2. 修复阿里云(OSS)特殊文件名称无法上传的问题. 3. 文件夹MD5提供配置项(默认关闭).

  3. 踏破铁鞋无觅处,从AsyncTask学Android线程池

    android对于主线程的响应时间限制的非常严格,稍有不慎就会遇到Application Not Responding(ANR)的弹框.用户可以轻点手指关掉你的APP.官方文档写的非常明确!同时,保持 ...

  4. (转)本地搭建环境wamp下提示不支持GD库的解决方法

    转自:http://www.zzdp.net/local-wamp-gd GD库是什么?GD库,是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片. ...

  5. (转)MVC一个页面多个submit

    转自:http://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mv ...

  6. (01背包 第k优解) Bone Collector II(hdu 2639)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639       Problem Description The title of this problem i ...

  7. 配置SecureCRT密钥连接Linux

    SSH公钥加密的方式使得对方即使截取了帐号密码,在没有公钥私钥的情况下,依然无法远程ssh登录系统,这样就大大加强了远程登录的安全性. 1.        编辑配置文件 /etc/ssh/sshd_c ...

  8. Java案例:超市库存管理系统

    案例介绍: 模拟真实的库存管理逻辑,完成超市管理系统的日常功能实现,见下图 案例需求分析: 根据案例介绍,我们进行分析,首先需要一个功能菜单,然后输入功能序号后,调用序号对应的功能方法,实现想要的操作 ...

  9. Digital Roots—HDU1013 2016-05-06 10:25 85人阅读 评论(0) 收藏

    Digital Roots Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  10. js-数组方法push

    <script type="text/javascript">        var arr=[1,2,3,4,5]        arr.push(6,7)      ...