1、Java代码优化

1.1 代码执行

  通常情况下,不必看应用的字节码。在平台是Android2.2(Froyo)和更高版本的情况下尤其如此,因在Android2.2中引入了实时(JIT)的编译器。Dalvik JIT编译器把Dalvik字节码编译成本地代码,这可明显加快执行速度。JIT编译器(JIT)可显著提高性能,因为:

  1. 本地代码直接由CPU执行,而不必由解释执行;
  2. 本地代码可为特定架构予以优化

  谷歌基准测试显示,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条:

  1. 不予优化:不予优化,因为应用在这些旧设备上运行得相当缓慢;
  2. 限制最低API:限制应用中Android API等级为最低8级,让它只能安装在Android2.2或更高版本上;
  3. 禁掉高耗功能:即使没有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 响应能力

  主线程主要处理的事情:

  1. 按键事件接收;(例如,View.onKeyDown()和Activity.onKeyLongPress());
  2. 绘制View(View.onDraw());
  3. 产生生命周期事件(例如,Activity.onCreate());

  Activity的onCreate()方法一般会包含调用setContentView或任何其他负责展开资源的方法。因为展开资源是一个开销相对较大的操作,所以你可通过降低布局(Layout,XML文件定义应用的外观)复杂性来使资源展开加快。几个降低布局复杂性的步骤如下:

  1. 使用RelativeLayout代替嵌套LinearLayouts,尽可能保持“扁平化”的布局。另外,减少创建的对象数量,也会使事件的处理速度加快
  2. 使用ViewStub推迟对象创建

  注意:因为可能有很多项目在列表中,所以要特别注意ListView布局。你可使用SDK的layoutopt工具来分析布局

  优化的基本原则是保持应用的持续响应,让主线程尽可能快地完成任务。这句话也常用另一个说法,在主线程当中尽可能少做事情。在大多数情况下,可通过把操作转移到另一个线程或推迟操作来加快应用响应速度,这两种技术通常并不会使代码更难维护。把任务转移到另一个线程之前,一定要确保你已充分了解任务执行太慢的原因。若响应慢的原因是坏的算法或实现,就去修改它们,将任务转移到另一个线程只是欲盖弥彰而已。

  写程序时,应始终假定下列两种情况:

  1. 网络很慢(正在试图连接的服务器甚至可能没有响应)
  2. 文件系统的访问速度很慢

  结论就是,不应该在主线程内进行网络操作或访问文件系统,因为缓慢的操作会拖累系统的响应能力。虽然在开发环境中,你可能永远不会遇到任何网络问题或任何文件系统的性能问题,但用户可能不像你那么幸运。

1.8 总结

  不要牺牲响应能力。这可能会加大应用开发的难度,而响应顺畅是应用成功的关键

2、NDK(native develop kit)入门

  Android的原生开发套件(NDK)是SDK的辅助工具,可用它把Android应用的一部分或全部用本地代码实现。字节码需由虚拟机解释,而本地代码可由设备处理器直接执行,没有任何中间步骤,执行速度更快,有时快很多。Dalvik的JIT编译器可将字节码编译为本地代码,减少应用字节码的解释次数(理想情况下仅有一次),而直接使用自己生成的本地代码,可让应用运行得更快。使用NDK时,是在开发环境中将代码编译为本地代码,而不是在Android设备上。

  使用本地代码和NDK的方式有以下两种:

  1. 应用的一部分用Java编写,另一部分用C/C++编写;
  2. 应用全部用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文件可以编译多个模块,每个模块属下列类型之一:

  1. APK程序   一般的Android程序,编译打包生成apk文件

  2. JAVA库  java类库,编译打包生成jar文件

  3. C\C++应用程序 可执行的C\C++应用程序

  4. C\C++静态库 编译生成C\C++静态库,并打包成.a文件

  5. C\C++共享库 编译生成共享库(动态链接库),并打包成.so文, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。  

2.7 总结

  本章介绍了使用本地代码提高性能的办法。精心雕琢的本地代码很少会降低性能,而使用NDK的原因也不只是提高性能。下面总结了使用NDK的理由:

  • 重用现有代码,而不是在Java中重写一切;
  • 编写新的代码,在其他不支持Java的平台上使用;
  • 要在没有JIT编译器(Android2.1或更早版本)的旧Android设备上运行应用,那本地代码是提供顺畅用户体验的唯一出路;
  • 即使Android设备上已有JIT编译器,在应用中使用本地代码还是可提升用户体验。

  前两个原因非常重要,在某些情况下,你可能需要为了它们牺牲性能(前提是不会影响到用户体验,或至少不会超出用户的忍耐范围)和许多开发者一样,你可用的资源有限,若想让尽可能多的人采用你开发的应用,不要局限在单一平台,那不会使你的收益最大化。

3、NDK进阶

《Android应用性能优化》1——代码的更多相关文章

  1. Android应用性能优化(转)

    人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...

  2. Android客户端性能优化(魅族资深工程师毫无保留奉献)

    本文由魅族科技有限公司资深Android开发工程师degao(嵌入式企鹅圈原创团队成员)撰写,是degao在嵌入式企鹅圈发表的第一篇原创文章,毫无保留地总结分享其在领导魅族多个项目开发中的Androi ...

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

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

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

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

  5. android app性能优化大汇总

    这里根据网络上各位大神已经总结的知识内容做一个大汇总,作为记录,方便后续“温故知新”. 性能指标: (1)使用流畅度:  图片处理器每秒刷新的帧数(FPS),可用来指示页面是否平滑的渲染.高的帧率可以 ...

  6. Android开发性能优化总结(一)

    安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. ...

  7. Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手

    图片加载性能优化永远是Android领域中一个无法绕过的话题,经过数年的发展,涌现了很多成熟的图片加载开源库,比如Fresco.Picasso.UIL等等,使得图片加载不再是一个头疼的问题,并且大幅降 ...

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

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

  9. Android之ListView性能优化——一行代码绑定数据——万能适配器

    如下图,加入现在有一个这样的需求图,你会怎么做?作为一个初学者,之前我都是直接用SimpleAdapter结合一个Item的布局来实现的,感觉这样实现起来很方便(基本上一行代码就可以实现),而且也没有 ...

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

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

随机推荐

  1. verilog基础--altera培训

    参数化 Localparam :与prameter一样,但不能被重写. Verilog-2001 格式, module mult_acc #(parameter size = 8 ) (...); 数 ...

  2. Python安装setuptools遇到的MARKER_EXPR错误

    # python setup.py install Traceback (most recent call last):   File "setup.py", line 11, i ...

  3. AWS S3 CLI的安装和配置

    以Ubuntu系统为例,说明如何使用CLI调试AWS S3环境: 1. 安装 # sudo pip install awscli 2. 配置AWS CLI 执行命令aws configure, 注意, ...

  4. 反编译 轻松调频 Android APP 下载“飞鱼秀”录音

    经常听“飞鱼秀”,但是由于时间的原因,只能听回放,但是轻松调频的APP做的有点儿... 听回放的时候经常会中断,还不能拖动进度条,就决定把录音下载下来听. 1.反编译apk(Android反编译过程见 ...

  5. Windows.Web.Http.HttpClient.GetStringAsync 总是返回相同的结果

    今天在测试博客园新闻WP8.1客户端的时候,发现电脑上浏览的新闻已经更新了.但手机上的还没更新,于是想到肯定是有bug了.于是建了一个Web测试项目,发现只有第一次发出了请求.一开始以为是MVVM的问 ...

  6. LeetCode147:Insertion Sort List

    题目: Sort a linked list using insertion sort. 解题思路: 按题目要求,直接进行插入排序 实现代码: #include <iostream> us ...

  7. Dalsa线扫相机配置-一台工控机同时连接多个GigE相机

    如图,我强悍的工控机,有六个网口. 实际用的时候连了多台相机,为了偷懒我就把六个网口的地址分别设为192.168.0.1~192.168.0.6,以为相机的IP只要设在192.168.0这个网段然后随 ...

  8. ASP.NET Core 装X利器SignalR:电子画板

    电子画板开发需求 教师端需求: 教师登录后能创建房间(教室) 学生加入房间后有通知提醒 教师能够解散房间 基本的画板功能   学生端需求: 能够切换不同在线的房间 能够收到新建房间的通知 能够收到房间 ...

  9. 自定义两个控件,一个是显示图标和文字的矩形,一个是带边框的label(但是不是label)

    记录遇到的两个坑 坑1. 一开始我继承button 来实现下面的控件1,后面发现button没有双击事件.就改成继承UserControl了.重新编译,导致设计时的控件文本全部被清空,因为UserCo ...

  10. Oracle function函数赋权

    -- 1.赋权 -- 在原有权的账号下个执行 grant select on psprd.functionName to user; -- 2. 别名 -- 在需要使用别名的账号下执行 CREATE ...