android 应用性能提升
2013-03-20 06:47 java20130722 阅读(193) 评论(0) 编辑 收藏 举报虽然Android智能手机和平板电脑的速度一天比一天快,但是开发者必须记住一点:他们开发的应用程序仍在一种资源紧张的环境下运行,这种环境主要依赖性能与最新的台式机或笔记本电脑无法比拟的电池和处理器。下面介绍的一些方法可以帮助你的应用程序“瘦身”或者说“Android提升开发性能十大要点”,以便它们在今天和明天的Android设备上最顺畅地运行。
先来说说确保应用程序响应迅即的几个编程要点。
第一个要点:首先要有良好的编程习惯
要成为一名优秀的资源管理员;既要运用常识,还要使用公认的算法和标准的设计模式。在资源使用方面,如果你打开了资源,要记得关闭资源。要尽量晚地获取,尽量早地释放。这些由来已久的编程准则同样适用于你的Android应用程序,如果它们使用底层的设备服务,更是如此。
比如说,假设你编写的一个应用程序依赖基于位置的服务。除非你绝对有必要,否则不要开始注册、获取位置最新信息;而且要确保,一旦你不再需要这些信息,就要取消获取最新信息的注册。这将帮助你避免不必要地耗费设备电池电量或占用系统资源。
第二个要点:让阻塞操作远离主用户界面线程
想确保你的应用程序运行起来很灵活,就要使用AsyncTask、线程、IntentService或自定义后台服务来处理脏活。应使用装入器来简化装入时间长的数据(如游标)的状态管理。你无法容忍你的应用程序在某个操作正在处理的时候出现滞后或停顿。 如果某个操作很费时间和资源,
就要卸载这部分操作、对它进行异步处理,那样你的应用程序仍保持响应迅即,用户可以处理他们的事务。这个原则适用于下列操作:磁盘读写,访问内容提供方、数据库和互联网,以及解析和其他长时间的任务。
为了确定是否需要优化,优化后性能是否得到提升,针对性能进行度量是非常必要的。
1. 时间测量-----------Java和Android提供了以下的API,让应用可以测量时间及性能:
System.currentTimeMillis
System.nanoTime
Debug.threadCpuTimeNanos
SystemClock.currentThreadTimeMills
SystemClock.elapsedRealtime
SystemClock.uptimeMillis
以上函数即使有些方法返回时间用纳秒表示,并不意味着精度是纳秒级的。实际精度取决于平台。毫秒精度的一样的道理。测试时间的典型代码
long startTime = System.nanoTime();
//这里进行待测量的操作
long duration = System.nanoTime() -startTime;
System.out.println("Duration:"+ duration);
这段代码全引用的java类,因此可以用在Android以外的平台。而Debug和SystemClock类是Android独有的。尽管System.currentTimeMillis()可以作为测量时间的手段,但不建议使用这种方法,原因如下:
1)其精度和准确度不够
2)更改系统时间会影响其结果
最好使用System.nanoTime(),因为它提供了更好的精度和准确度System.nanoTime()没有定义参考时间,只能用来测量时间间隔。而System.currentTimeMilis()返回值是UTC时间1970年1月1日00:00:00到现在的毫秒数。
给出测试System.nanoTime()本身需要耗费的时间的代码。本身的执行时间在750纳秒的数量级上。注意进行测量的操作可能因为多线程而被中断几次,来让出CPU时间给别的线程。因此,测量结果可能包括一些执行其他代码的时间,这可能会得出不正确的时间测量结果,产生误导。可以使用Android的Debug.threadCpuTimeNano()方法测量代码的执行时间,这个方法更好些。因为Debug.threadCpuTimeNanos()只测量在当前线程中所花费的时间,所以它的结果更准确。不过,如果要测量的部分运行在多个线程上,只调用一次Debug.threadCpuTimeNanos()不会给出准确的估值,必须在所有涉及的线程调用此方法并把结果相加。
给出用Debug.threadCpuTimeNanos() 测量运行时间的代码。
2. 方法调用跟踪---------------
一旦确定在哪儿花费了过多时间,就需要了解更多细节,找出罪魁祸首的方法。可以利用跟踪工具创建方法跟踪文件,之后用Traceview工具进行分析。
Android提供了Debug.startMethodTracing()方法来创建跟踪文件,然后用Traceview工具调试和分析应用。代码如下:Debug.startMethodTracing("/sdcard/awesometrace.trace");
// 需要跟踪的操作
Debug.stopMethodTracing();
现在在/mnt/sdcard/ 目录下会有名为awesometrace.trace的文件,在Eclipse DDMS中可以取到。然后用tools目录下的Traceview工具进行分析。Traceview中的信息包括:
Name:方法名
Incl %: 此方法中占的时间百分比(包含子方法)
Inclusive: 此方法所花毫秒数(包含子方法)
Excl %:此方法所占时间百分比(不包含子方法)
Exclusive: 此方法所花毫秒数(不包含子方法)
Calls+RecurCalls/Total: 调用和递归调用次数
Time/Call: 平均每次调用时间。
因为VM启用跟踪会减缓运行速度,不要把这个时间值当做最终的结果。这些时间值只是为了确定哪个方法或运行方式速度更快。如果点击一个方法的名称,Traceview会告诉你该方法的更详细的信息。另一种跟踪调用及使用Traceview的方式是直接从Eclipse DDMS视图中生成跟踪文件。选定一个线程后,可以点击Start Method Profiling ,然后再次单击就停止剖析,开始分析。另外,给出本地方法跟踪的办法。NDK本地方法利用QEMU进行跟踪。如何生成QEMU的跟踪文件,将其转换成traceview可以处理的文件等。需要用到tracedump工具。
3. 日志-------日志函数在NDK中也可以使用,可以用logcat来记录C/C++代码的消息
第三个要点:使用最新的Android软件开发工具包(SDK)版本、应用编程接口(API)和最佳实践
确保你开发的应用程序是最新的,因而要使用Android平台提供的最新工具。随着Android平台不断发展,它也在不断改进。一些功能可能已被弃用,或者换成了更好的功能。核心API得到了修正版
(bug fix)和性能改进。已经引入了装入器等新的API,帮助开发者编写出运行更稳定、响应更迅即的应用程序。你知道可以启用Android3.0应用程序中的硬件加速功能吗?赶紧启用吧!要明白最佳实践会随着时间的变化而变化。明智的开发者密切关注Android平台的新功能、哪些功能不再被推荐。
第四个要点:考虑使用限制模式(Strict Mode)
你可以使用名为限制模式(StrictMode)的AndroidAPI,帮助你查明哪里违反了几个良好的编程习惯。StrictMode会帮助你确认你的应用程序是不是存在内存泄漏,并且检测你的应用程序是不是在试图执行长时间的阻塞操作,这些操作应该被卸载到线程或别的渠道(参阅第二个要点)。 Android2.3里面引入StrictMode类(android.os.StrictMode).
第五个要点:在发布应用程序之前,禁用或尽量少用调试和诊断
如果你的Android应用程序开发起来需要一些时间,你可能已将一些日志和调试代码嵌入到了应用程序中。写入到日志及其他此类输出系统给性能带来了影响。确保在发布应用程序之前,尽量少用或完全禁用这些功能。现在不妨说说如何运用良好的用户界面设计原则,让你应用程序的屏幕更快速地装入:
第六个要点:确保你设计的布局简单、简练和浅层
简单的屏幕有助于阅读起来最轻松,而简单的布局装入起来最快速。你不应该过于深层地嵌套你的布局,或者用不必要的过多视图(View)控件塞满屏幕。花些时间来开发用户可以高效使用的简练用户界面,而不是试图把太多功能塞入到单单一个屏幕上。这不但有助于提升应用程序的性能,还有助于让你的应用程序对用户来说更高效。Fragments有助于在不影响灵活地针对不同类型的设备进行设计的情况下,划分用户界面功能。
布局优化-------- 1. setContentView调用花费的时间取决于布局的复杂性:资源数据越大解析越慢,而更多的类也让布局实例化变慢 2. 调用setContentView()几乎占用了从onCreate()开始到onResume()结束之间所有时间的99% 3. 要节约时间,大多数基于同样的原则:减少创建对象的数量。消除不必要的对象,或者推迟创建对象 4. 采用嵌套的线性布局会深化布局层次,从而导致布局和按键处理变慢。 5. 合并布局。另一种减少布...局层次的技巧是用<merge />标签来合并布局。 Android布局的父视图是一个FrameLayou,如果你的布局的最上层也是一个FrameLayout,就可以用<merge />标签代替它,减少一层布局6. 重用布局,Android支持在XML布局中使用<include /> 标签,用来包含另一个布局。<include /> 标签可用于两个目的: 1) 多次使用相同的布局 2) 布局有一个通用的组成部分,或有部分依赖于设置配置(例如,屏幕方向纵向或横向)7. ViewStub推迟初始化是个方便的技术,可以推迟实例化,提高性能,还可能会节省内存(如果对象从未创建过)ViewStub是轻量级且不可见的视图,当需要时,在自己的布局中可以用它来推迟展开布局。下次遇到相关代码后,将代码整理在这里布局工具--------
1.hierarchyviewer 用来查看布局的
2.layoutopt 用于检测布局文件质量的
第七个要点:让你应用程序的资源适合目标设备
添加适合特定设备配置的资源,那样它们就能尽可能高效地装入。我们在谈论图形资源时,
这点尤为重要。如果你添加了可利用的庞大图像资源,需要装入和调整大小,就无法有效地使用其他的应用程序资源。另一个要点就是,如果你准备你的应用程序可以在许多设备上运行,为了让应用程序软件包文件保持合理的大小,应该最初只添加运行应用程序所需要的核心资源,然后让应用程序下载适合该设备的内容。
第八个要点:使用Hierarchy Viewer工具
Hierarchy Viewer工具可以帮助你调试你的应用程序布局。它还提供了宝贵的分析信息,以便了解布局里面的每一个视图控件测量、渲染和绘制要花多少时间。只有准确找到了问题的根源,问题解决起来才容易。
第九个要点:使用layoutopt工具
Layoutopt工具是一款简单的命令行工具,它可以帮助你找到不必要的控件嵌套以及缩减布局资源的其他方法,以便尽量减少资源的使用。它让你可以了解哪些布局控件可能是多余的或不必要的。控件越少、布局层次越浅,性能就越好。最后,你认为你的应用程序做到了最好吗?现在该对它测试一下了。
第十个要点:使用Traceview及其他Android工具进行分析
Android SDK随带了许多工具,可用来对你的应用程序进行分析。其中最流行的工具恐怕莫过于
Traceview,这款图形化工具可以帮助你调试和找到应用程序中的性能瓶颈。不妨看看
Android说明文档中介绍的一些调试工具。现在最热门的2款智能手机操作系统为安卓和
ios。安卓是Google出的开放式手机系统,IPHONE是Mac出的封闭手机系统。
结语
提升Android应用性能的方法有很多,有些需要使用特定的算法,有些依赖切实可行的调试和性能监测技术。幸运的是,Android平台随带了众多免费的实用工具,可以帮助跟踪和解决应用程序中的性能问题。