在应用运行时,可以使用Debug类打开操作日志记录功能,打开后Android会详细记录应用花在每个线程以及线程的每个函数的调用时间。操作日志记录完毕后,可以使用Android SDK自带的traceView工具将应用操作日志图形化显示,在应用开发的过程中,可以用它来观察应用的性能瓶颈。
记录应用操作日志的方法有两种:
利用Debug类的startMethodTracing和stopMethodTracing函数分别来打开和关闭日志记录功能。
这个方法的优点在于精确,应为可以指定需要衡量的函数,但它的缺点是需要修改应用函数源码。使用DDMS工具来启动日志记录功能,这种方法不是很精确,因为它不是通过修改源码实现,而是在DDMS工具中指明何时启用和停止日志
使用第一种方式的时候,在应用只要在源码中调用Debug类的startMethodTracing函数,指定保存操作日志的文件名就可以开始跟踪记录操作日志。要停用日志功能,只需要调用stopMethodTracing函数即可。即:
Debug.startMethodTracing("tracedemo");
.
.
.
Debug.stopMethodTracing();
之后就会在sd卡目录生成一个tracedemo.trace文件,使用adb命令把它下载到本地开发机
adb pull /sdcard/tracedemo.trace
使用Android SDK中的traceview打开收集到得操作日志,
traceview tracedemo.trace
使用第二种方式很简单,打开DDMS界面,选中对应的进程,点击“start Method Profilling”按钮开始记录,再点击一次结束记录
TraceView的界面分为两部分,上面是时间线(Time Panel),应用中运行的每个线程以单独一行显示。下面是详细日志面板,详细列出各函数运行的耗时分析,如下图所示
详细日志面板参数说明
参数 | 说明 |
---|---|
Incl Cpu Time(%);Incl Cpu Time | 包含时间(Inclusive Time)表示花在执行函数的时间,包括函数调用的所有子函数运行消耗的时间。 |
Excl Cpu Time(%);Excl Cpu Time | 独占时间(Exclusive time)比奥斯只花在执行函数的时间,不包括函数调用的所有子函数运行消耗的时间 |
Calls+Recur;Calls/Total | 虽然用一列显示,其实该列包含了两个信息,分别是“Calls+Recur”和“Calls/Total”。“Calls+Recur”表示函数被调用的次数(前者)和被递归调用的次数(后者),而“Calls/Total”表示子函数被父函数调用的次数(前者)和其总的被调用次数(后者)。 |
Cpu Time/Call | 对应函数每次调用平均消耗的Cpu的时间 |
通过分析Traceview我们可以分析那些方法耗时比较严重,从而找到性能瓶颈,继而解决问题。
除了上面两种方式来记录操作日志之外,还可以通过Android系统中am命令来启用日志记录功能。与ddms命令类似,am的profile子命令可以在进程运行时打开操作日志记录功能,其使用格式如下:
在TraceView的详细日志面板中可以以层次的方式展开每个函数,方便开发人员观察函数之间的调用关系,如当前函数被哪个函数所调用,当前函数直接调用了哪些函数等。但这种方式还不是很直观,在Android中,dmtracedump命令可以用来图形化的显示函数之间的层次调用关系。
dmtracedump命令依赖开源的dot命令生成函数调用,而dot是graphviz包得一部分,graphviz是一个可以从文本形式的描述文件中生成图片的程序,用法可以参考其官网 http://www.graphviz.org.在使用之前,需要安装graphviz包,安装命令如下:
brew install graphviz(mac)
dmtracedump命令的使用格式是“dmtracedump[参数列表]日志文件”,例如:
dmtracedump -g tracedemo.png tracedemo.trace
可以生成类似下面的图
以下是dmtracedump命令的参数说明表
参数 | 说明 |
---|---|
-d(日志文件) | 与指定的日志文件做对比 |
-g<输出的图像文件> | 以图形方式显示调用树并输出到指定的文件中 |
-k | 保存中间用于生产调用树图像的dot文件 |
-h | 与以HTML格式输出 |
-o | 只是显示日志文件,而不做任何处理 |
-s<排序js文件> | 当以HTML格式输出时,这个参数指定在HTML文件中进行排序的javascript文件 |
-t<百分比> | 要显示的函数调用包含时间(inclusive time)阀值,对于子节点来说,该阀值是其调用包含时间相对于父节点调用包含时间的百分比,默认值是20%,即只输出调用包含时间是父节点总调用包含时间20%的函数到最终文件中 |
例如,除了生成调用树图像文件,也可以生产一个详细的html网页发布到web服务器,供开发者在线浏览
dmtracedump -h tracedemo.trace > temp.html