《Android应用性能优化》1——代码
1、Java代码优化
1.1 代码执行
通常情况下,不必看应用的字节码。在平台是Android2.2(Froyo)和更高版本的情况下尤其如此,因在Android2.2中引入了实时(JIT)的编译器。Dalvik JIT编译器把Dalvik字节码编译成本地代码,这可明显加快执行速度。JIT编译器(JIT)可显著提高性能,因为:
- 本地代码直接由CPU执行,而不必由解释执行;
- 本地代码可为特定架构予以优化
谷歌基准测试显示,Android2.2的代码执行速度比Android2.1块2到5倍。虽说代码的具体功能会对结果产生很大影响,但可肯定的是,使用Android2.2及更高版本会显著提升速度。
对于无JIT的Android2.1或更早的版本而言,优化策略的选用可能会因此受到很大影响。若打算针对运行Android1.5(Cupcake)、1.6(Donut),或2.1(eclair)的设备开发,你要先仔细地审查应用在这些环境下需提供哪些功能。此外,这些运用Android早起版本的旧设备是没新设备强劲的。尽管运行Android2.1和更早版本的设备所占的市场份额正在萎缩,但直到2011年12月,其数量仍占有约12%。可选策略有3条:
- 不予优化:不予优化,因为应用在这些旧设备上运行得相当缓慢;
- 限制最低API:限制应用中Android API等级为最低8级,让它只能安装在Android2.2或更高版本上;
- 禁掉高耗功能:即使没有JIT编译器,也要针对旧设备优化,给用户以舒畅的体验。也就是说禁掉那些非常耗CPU资源的功能
1.3 缓存结果
使用SparseArray充当缓存
定义一个缓存时,使用HashMap,可胜任这项工作。不顾,Android定义了SparseArray类,当键是整数时,它比HashMap效率更高。因为HashMap使用的是java.lang.Integer对象,而SparseArray使用的是基本类型int。因此使用HashMap会创建很多Integer对象,而使用SparseArray则可避免这种情况。
注意:Android定义了多种类型的稀疏数组(sparse array):SparseArray(键为整数,值为对象)、SparseBooleanArray(键为整数,值为boolean)和SparseIntArray(键为整数,值为整数)
LRU和MRU策略
所谓的LRU(Least recently used)算法的基本概念是:当内存的剩余的可用空间不够时,缓冲区尽可能的先保留使用者最常使用的数据,换句话说就是优先清除“较不常使用的数据”,并释放其空间。之所以“较不常使用的数据”要用引号是因为这里判断所谓的较不常使用的标准是人为的、不严格的。所谓的MRU(Most recently used)算法的意义正好和LRU算法相反,Android现在没有类似MruCache类,考虑到MRU缓存不常用,这并不奇怪
1.4 API等级
版本的分化主要体现在:屏幕分辨率、实体物理键盘、硬件图形加速器及处理器上
1.6 响应能力
主线程主要处理的事情:
- 按键事件接收;(例如,View.onKeyDown()和Activity.onKeyLongPress());
- 绘制View(View.onDraw());
- 产生生命周期事件(例如,Activity.onCreate());
Activity的onCreate()方法一般会包含调用setContentView或任何其他负责展开资源的方法。因为展开资源是一个开销相对较大的操作,所以你可通过降低布局(Layout,XML文件定义应用的外观)复杂性来使资源展开加快。几个降低布局复杂性的步骤如下:
- 使用RelativeLayout代替嵌套LinearLayouts,尽可能保持“扁平化”的布局。另外,减少创建的对象数量,也会使事件的处理速度加快
- 使用ViewStub推迟对象创建
注意:因为可能有很多项目在列表中,所以要特别注意ListView布局。你可使用SDK的layoutopt工具来分析布局
优化的基本原则是保持应用的持续响应,让主线程尽可能快地完成任务。这句话也常用另一个说法,在主线程当中尽可能少做事情。在大多数情况下,可通过把操作转移到另一个线程或推迟操作来加快应用响应速度,这两种技术通常并不会使代码更难维护。把任务转移到另一个线程之前,一定要确保你已充分了解任务执行太慢的原因。若响应慢的原因是坏的算法或实现,就去修改它们,将任务转移到另一个线程只是欲盖弥彰而已。
写程序时,应始终假定下列两种情况:
- 网络很慢(正在试图连接的服务器甚至可能没有响应)
- 文件系统的访问速度很慢
结论就是,不应该在主线程内进行网络操作或访问文件系统,因为缓慢的操作会拖累系统的响应能力。虽然在开发环境中,你可能永远不会遇到任何网络问题或任何文件系统的性能问题,但用户可能不像你那么幸运。
1.8 总结
不要牺牲响应能力。这可能会加大应用开发的难度,而响应顺畅是应用成功的关键
2、NDK(native develop kit)入门
Android的原生开发套件(NDK)是SDK的辅助工具,可用它把Android应用的一部分或全部用本地代码实现。字节码需由虚拟机解释,而本地代码可由设备处理器直接执行,没有任何中间步骤,执行速度更快,有时快很多。Dalvik的JIT编译器可将字节码编译为本地代码,减少应用字节码的解释次数(理想情况下仅有一次),而直接使用自己生成的本地代码,可让应用运行得更快。使用NDK时,是在开发环境中将代码编译为本地代码,而不是在Android设备上。
使用本地代码和NDK的方式有以下两种:
- 应用的一部分用Java编写,另一部分用C/C++编写;
- 应用全部用C/C++写
2.1 处理器
- ×86——Intel架构
- armeabi——ARM架构,是Android设备的主导架构
- MIPS——运行Android2.2的MIPS只能手机早在2011年6月就通过了Android兼容性测试,但官方Android NDK仍然不支持MIPS ABI
2.3 Application.mk
Application.mk用于在指定整个应用的共同变量,Android.mk用来指定想构建什么模块以及如何构建
2.4 Android.mk是Android开发中,用来编译JNI代码的
在开发工具中,new JNI 即可创建一个 android.mk文件;
一个Android.mk文件可以编译多个模块,每个模块属下列类型之一:
APK程序 一般的Android程序,编译打包生成apk文件
JAVA库 java类库,编译打包生成jar文件
C\C++应用程序 可执行的C\C++应用程序
C\C++静态库 编译生成C\C++静态库,并打包成.a文件
C\C++共享库 编译生成共享库(动态链接库),并打包成.so文, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。
2.7 总结
本章介绍了使用本地代码提高性能的办法。精心雕琢的本地代码很少会降低性能,而使用NDK的原因也不只是提高性能。下面总结了使用NDK的理由:
- 重用现有代码,而不是在Java中重写一切;
- 编写新的代码,在其他不支持Java的平台上使用;
- 要在没有JIT编译器(Android2.1或更早版本)的旧Android设备上运行应用,那本地代码是提供顺畅用户体验的唯一出路;
- 即使Android设备上已有JIT编译器,在应用中使用本地代码还是可提升用户体验。
前两个原因非常重要,在某些情况下,你可能需要为了它们牺牲性能(前提是不会影响到用户体验,或至少不会超出用户的忍耐范围)和许多开发者一样,你可用的资源有限,若想让尽可能多的人采用你开发的应用,不要局限在单一平台,那不会使你的收益最大化。
3、NDK进阶
《Android应用性能优化》1——代码的更多相关文章
- Android应用性能优化(转)
人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...
- Android客户端性能优化(魅族资深工程师毫无保留奉献)
本文由魅族科技有限公司资深Android开发工程师degao(嵌入式企鹅圈原创团队成员)撰写,是degao在嵌入式企鹅圈发表的第一篇原创文章,毫无保留地总结分享其在领导魅族多个项目开发中的Androi ...
- Android APP 性能优化的一些思考
说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才 ...
- Android app 性能优化的思考--性能卡顿不好的原因在哪?
说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才 ...
- android app性能优化大汇总
这里根据网络上各位大神已经总结的知识内容做一个大汇总,作为记录,方便后续“温故知新”. 性能指标: (1)使用流畅度: 图片处理器每秒刷新的帧数(FPS),可用来指示页面是否平滑的渲染.高的帧率可以 ...
- Android开发性能优化总结(一)
安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. ...
- Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手
图片加载性能优化永远是Android领域中一个无法绕过的话题,经过数年的发展,涌现了很多成熟的图片加载开源库,比如Fresco.Picasso.UIL等等,使得图片加载不再是一个头疼的问题,并且大幅降 ...
- 包建强的培训课程(9):Android App性能优化
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- Android之ListView性能优化——一行代码绑定数据——万能适配器
如下图,加入现在有一个这样的需求图,你会怎么做?作为一个初学者,之前我都是直接用SimpleAdapter结合一个Item的布局来实现的,感觉这样实现起来很方便(基本上一行代码就可以实现),而且也没有 ...
- (转) Android开发性能优化简介
作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...
随机推荐
- modelsim仿真中Altera库的用法
添加altera 库 实例: 把建立lpm_mux IP时生成的.v文件lpm_mux_ip.v和编写的测试脚本文件放在一起,在modelsim中建立工程,把下面两个文件添加到工程中 直接compil ...
- python调用dll方法
在python中调用dll文件中的接口比较简单,实例代码如下: 如我们有一个test.dll文件,内部定义如下: extern "C"{ int __stdcall test( v ...
- 关于RabbitMQ一点
RabbitMQ是AMQP(高级消息队列协议)的标准实现,理论上可以保证消息发送的准确性 RabbitMQ是用Erlang语言编写的,而Erlang语言具有以下特点: 并发性--Erlang支持超大量 ...
- 在mui中创建aJax来请求数据..并展示在页面上
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <m ...
- jQueryUI datepicker 报错: TypeError: inst is undefined
前提:要引用的js等都引用好了 调用日期控件的input: <input id="starttime" name="starttime" class=&q ...
- (二分匹配 模板)过山车 -- hdu --2063
链接: http://acm.hdu.edu.cn/showproblem.php?pid=2063 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- Codeforces807 B. T-Shirt Hunt 2017-05-08 23:23 175人阅读 评论(0) 收藏
B. T-Shirt Hunt time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- JSTL自定义函数完成ACL即时认证
即时认证是指,用户进行查询或更新操作时,判断该用户进行是否对该操作有权限. 这里以判断用户是否有删除权限为例.如果用户有删除权限,即显示该按钮:如果没有删除权限,则不显示该按钮. 1.Manager层 ...
- 为上海莫大型重工企业提供基于TFS的软件研发流程管理培训
这周,和微软公司的朋友一起,受上海莫大型重工企业的要求,为企业软件部门一个60多人的软件团队提供了为其2天的全流程培训,培训基于微软Team Foundation Server 2017(TFS 20 ...
- [翻译]NUnit---SetUp and SetUpFixture and Suite Attributes(十九)
SetUpAttribute (NUnit 2.0 / 2.5) 本特性用于TestFixture提供一个公共的功能集合,在呼叫每个测试方法之前执行.同时也用在SetUpFixture中,SetUpF ...