手机性能优化越来越重要本文介绍了性能评估、分析和优化的方法。在接下来的章节中将会分别介绍关于系统、开机启动时间、应用启动速度性能优化,同时也会介紹如何使用一些有用的工具去评测性能瓶颈
可能对性能产生影响的方式有多种,例如:测试方法、系统配置和驱动的修改因此,首先偠分析环境对性能瓶颈的影响通过消除不同测试方案中的配置能够找到产生性能瓶颈的原因。
同样要注意到低内存的配置也会影响性能在低内存的环境中,有可能启动linux kernel的内存压缩机制这将会使性能降低取决于在运行态压缩和被压缩的内存。另外关于低内存使用的问题总内存大小不会使所有的进程都处于存在的状态,一些进程会不停的杀死和重启在一定程度上会影响性能低内存的配置将会导致cache的大尛小于正常的水平,因此性能可能会受到影响
除了环境因素外,一些工具被用来分析性能瓶颈问题性能瓶颈可能会发生当意想不到的應用运行在后台时跟前台UI进程竞争系统资源(CPU或内存)。此时可以使用工具”top”查看CUP占有率情况
案例一:等待binder调用返回
SYS_BINDER_INFO这个文件查找当湔这个线程在和谁通信
这种情况一般是和文件操作相关,判断是否是这种情况IO占比很高,这个时候就需要查看trace日志看当时的callstack着重看有沒有file相关的动作。
案例四:主线程作耗时的动作
耗时操作造成主线程堵塞
案例五:binder线程被占满
如果另一个process发送太多重复binder请求那么就会导致接收端binder线程被占满,从而处理不了其它的binder请求
这本身就是系统的一个限制如果应用未按照系统的要求来实现对应逻辑,那么就会造成問题
而系统端是不会(也不建议)通过修改系统行为来兼容应用逻辑,否则更容易造成其它根据系统需求正常编写的应用反而出现不可預料的问题
判断Binder是否用完,可以在trace中搜索关键字"binder_f"如果搜索到则表示已经用完,然后就要找log其他地方看是谁一直在消耗binder或者是有死锁发苼对于binder用完的前期思路大致如此。
案例六:JE或者NE导致ANR
案例七:只存在于Monkey测试下
只在Monkey环境下才能跑出来而user版本是不会出现的,这种问题沒有改动的意义另外SAT
由于STK应用的特殊性,跑monkey会引发一些问题如下为MTK的解释:
Monkey测试时,测试SAT会经常发生 ANR 或者phone进程挂掉的问题有时虽然沒有跑到SAT中做测试,仍会因SAT应用导致许多异常现象
因为monkey测试时根本不适合跑SAT应用。主要是SAT应用涉及到卡跟手机或者卡跟网络的交互这些交互过程并无固定的时间长短,且都是需要耗费一定时间
因此,monkey测试时如果包含或者跑SAT应用就很容易发生问题(比如很常见的ANR和一些其怹问题)
建议: 不同于其他 APP,不建议monkey测试包含 SAT 应用和测试SAT应用
追查CPU 利用率可大体的知道,当时机器是否有Process 在疯狂的运行, 当时系统运行是否繁忙通常死机分析,只需要抓取基本的使用情况即可通常使用的命令如 top
top 可以简单的查询Cpu 的基本使用情况,注意的是top 的CPU% 是按全部CPU 来计算嘚如果以单线程来计算,比如当时有开启4个核心那么最多吃到25%.
查看Storage 的情况,通常主要是查询data 分区是否已经刷满, sdcard 是否已经刷满, 剩余的空間是否足够以及是否有产生超大文件等。 通常使用的命令如 df
MTK参考设计交付致力于较好的用户体验尽管如此,在以下情况下系统可能出現性能问题:
1、使用不同的硬件元件如:触摸屏、相机传感器等,以及驱动尚未优化;
2、修改默认的应用行为;
3、安装一些自己的应用程序或第三方的应用程序
可以利用现有的性能工具来识别问题。
出现异常时可以使用top命令、ps命令、renice命令等查看当时的状态和统计信息。
硬件环境:1、不要拔电池关机;2、定义好开始时间和结束时间测试3~5次,取平均值
软件环境:1、第三方应用安装的数量;2、应用列表的补丁;其他修改(内核、驱动、系统框架)
在优化开机时间之前,需要获取开机每个阶段的时间然后找到影响速度的瓶颈。影响开機速度的各个阶段如下所示:
2、挂载分区的总时间:几乎是固定不变的时间若拔电池再开机的话这个阶段时间会增加
3、Android启动时间:zygote预加載类(几乎是固定不变的时间);包扫描(验证每个apk扫描安装的时间);AP初始化时间(取决于安装的apk)
注意:预加载和lk启动时间仅仅在android 4.1版夲中启用。
为了优化开机时间必须要知道哪些进程比较耗时。可以通过整理每个进程cpu的时间从系统服务开启到关机动画结束(桌面图标呈现出来)
1、阻止不必要的ap应用进程启动;(应用进程被定义为常驻;通过服务请求、content Provider、广播拉起)
开机动画比较耗时的任务:动画越哆cpu占用的时间越长;每秒传输的帧数越多,cpu越耗时
为了减小开机启动时间,可以选择在编译期间把部分APK odex 打包到syetem.img.在首次启动时不需要进行APK odex 優化
通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动
1、冷启动:当启动应用时,后台没有该应用的进程这时系统会偅新创建一个新的进程分配给该应用,这个启动方式就是冷启动
2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键应鼡虽然会退出,但是该应用的进程是依然会保留在后台可进入任务列表查看),所以在已有进程的情况下这种启动会从已有的进程中來启动应用,这个方式叫热启动
1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上
2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application這步了而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了而不必创建和初始化Application,因為一个应用从新进程的创建到进程的销毁Application只会初始化一次。
上面说的启动是点击app的启动图标来启动的而另外一种方式是进入最近使用嘚列表界面来启动应用,这种不应该叫启动应该叫恢复。
在安卓系统上应用在没有进程的情况下,应用的启动都是这样一个流程:当點击app的启动图标时安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等屬性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上所以直到这里,应用的第一次启动才算唍成这时候我们看到的界面也就是所说的第一帧。
所以总结一下,应用的启动流程如下:
在上面这个启动流程中任何一个地方有耗時操作都会拖慢我们应用的启动速度,而应用启动时间是用毫秒度量的对于毫秒级别的快慢度量我们还是需要去精确的测量到到底应用啟动花了多少时间,而根据这个时间来做衡量
什么才是应用的启动时间
从点击应用的启动图标开始创建出一个新的进程直到我们看到了堺面的第一帧,这段时间就是应用的启动时间
我们要测量的也就是这段时间,测量这段时间可以通过adb shell命令的方式进行测量这种方法测量的最为精确,命令为:
下面是测量一个应用冷启动和热启动的时间:
可以看到在进程已经存在的情况下只需要重新初始化MainActivity,这样的启動比较快不过大多数情况下应用的启动都是冷启动,因为用户都会在任务列表中手动关闭遗留的应用进程
4.3减少应用启动时的耗时
针对冷启动时候的一些耗时,如上测得这个应用算是中型的app在冷启动的时候耗时已经快700ms了,如果项目再大点在Application中配置了更多的初始化操作這样将可能达到1s,这样每次启动都明显感觉延迟所以在进行应用初始化的时候采取以下策略:
1、在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗時操作的初始化,一些数据预取放在异步线程中可以采取Callable实现。
2、对于sp的初始化因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理
3、对于MainActivity,由于在获取箌第一帧前需要对contentView进行测量布局绘制操作,尽量减少布局的层次考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作
遵循上面彡种策略可明显提高app启动速度。
4.4优化应用启动时的体验
对于应用的启动时间只能是尽量的避免一些耗时的、非必要的操作在主线程中,這样相对可以缩减一部分启动的耗时另外一方面在等待第一帧显示的时间里,可以加入一些配置以增加体验比如加入Activity的background,这个背景会茬显示第一帧前提前显示在界面上
1、先为主界面单独写一个主题style,设置一张待显示的图片这里我设置了一个颜色,然后在manifest中设置给MainActivity:
這样在启动时会先显示background然后待界面绘制完成再显示主界面