精通安卓性能优化-第六章(三)

Native Tracing

除了使用startMethodTracing() API分析Java方法外,安卓同样支持native tracing(包括核心代码)。Native tracing也被称为QEMU tracing。本段学习如何产生QEMU trace文件,怎么样将他们转换为Traceview可以理解的文件。
为了产生QEMU trace,需要做两件事:
(1) 使用-trace选项启动emulator(比如,"emulator –trace mytrace –avd myavd")
(2) 启动然后停止native tracing,通过调用Debug.startNativeTracing()和Debug.stopNativeTracing(),或者通过按F9键(第一次启动tracing,第二次将停止)
在PC的AVD traces目录下,可以发现一个mytrace目录,包含几个QEMU模拟器trace文件:
(1) qtrace.bb
(2) qtrace.exc
(3) qtrace.insn
(4) qtrace.method
(5) qtrace.pid
(6) qtrace.static

NOTE:QEMU是一个开源模拟器。参考http://wiki.qemu.org。

为Traceview产生Trace文件

为了在Traceview中使用这些traces,就像Java方法那样,需要产生Traceview可以理解的trace文件。为了做到这些,需要使用tracedmdump命令(不要和SDK Tool中的dmtracedump命令混淆,那个是用来将调用栈产生成树表的)。Tracedump命令定义在Android源文件build/envsetup.sh中。为了访问这个命令,你需要下载Android源代码并且编译Android。
下载完整的Android代码,参考:
http://source.android.com/source/downloading.html
编译Android,参考:
http://source.android.com/source/building.html
你可以同样使用Android源代码编译自己的emulator,而不是依赖于SDK的那个。一旦Android编译完成,已经有了用来创建Traceview能够理解的文件的所有工具。
在AVD的traces目录,你可以简单的运行tracedmdump mytrace,将会创建一个可以使用Traceview打开的trace文件,如Figure 6-5所示。保证你的路径已经设置好了,所有的tracedmdump的命令可以成功的执行。如果tracedmdump失败,给出”command not found”错误,很可能是没有正确设置路径。比如,tracedmdump将调用在out/host/linux-x86/bin目录下的post_trace。

Figure 6-5 使用Traceview跟踪native


尽管同样的用户界面,在Figure 6-5看到的是native函数的列表,比如vsnPrintf()和sys_open(),对应#10和#13。
被tracedmdump创建的两个文件代表同样的数据:
(1) dmtrace
(2) dmtrace.html
第一个是被Traceview使用的文件,第二个可以被任何浏览器打开,包括Lynx。

NOTE:在使用tracedmdump的时候很多用户报告问题,而且错误信息不是很清楚。如果你遇到问题,在网上查找解决方案,因为很可能某个人已经遇到了同样的问题,并且发布了一个解决方案。

有些时候简单的有一个实时的、人们可以接触到的描述,可以极大的帮助你了解应用中发生了什么。在成熟的调试工具引进之前Logging信息已经被使用了很长一段时间,许多开发者依赖于log去调试和分析应用。

Logging

就像我们在很多listing中看到的一样,可以使用Log类打印信息到LogCat。除了Java传统的logging机制比如Sytem.out.println(),Android定义了6个Log级别,每个都有它自己的方法:
(1) verbose(Log.v)
(2) debug(Log.d)
(3) info(Log.i)
(4) warning(Log.w)
(5) error(Log.e)
(6) assert(Log.wtf)
比如,调用Log.v(TAG, “my message”)等同于Log.println(Log.VERBOSE, TAG, “my message”)。

NOTE:Log.wtf()方法在API 8引入,Log.ASSERT在API 1就开始存在。如果你希望使用ASSERT log级别,但是希望保证兼容老的安卓设备,使用Log.pringln(Log.ASSERT, …)而不是Log.wtf(…)。

你可以在Eclipse中使用LogCat(Window->Show View->LogCat)或者在终端(adb logcat,或者简单的从adb shell使用logcat),查看你的应用运行时的产生的信息。
因为可能会显示很多信息,许多不是来自于你的应用,你需要创建filters,这样可以集中于与你相关的输出。你可以基于tags、优先级、和PID过滤信息。在Eclipse中,你可以使用Create Filter功能,如Figure 6-6所示。

Figure 6-6 使用Eclipse创建LogCat


Eclipse当成不支持创建多个tag的Filter,所以你需要的话,需要使用adb logcat。比如,仅仅显示Debug或者以上的级别(即Debug, Info, Warning, Error和Assert)的MyTag标签的信息,和在Warning级别或者以上的MyOtherTag信息,你可以:
adb logcat MyTag:D MyOtherTag:W *:S
保证不要忘掉*:S部分,因为它意味着所有的其他Log信息将被排除(S表示Silent)。
Logging函数同样在NDK可用,所以你可以在C/C++代码中使用LogCat。函数定义在NDK的android/log.h中:
(1) __android_log_write
(2) __android_log_print
(3) __android_log_vprint
(4) __android_log_assert
比如,等同于Log.i(“MyTag”, “Hello”)的将是__android_log_write(ANDROID_LOG_INFO, “MyTag”, “Hello”).
因为这些是Android独有的函数,它们的使用使得你的代码有点啰嗦,推荐你为这些函数创建一个wrapper。事实上,Android的源代码已经在cutils/log.h中有做过,创建了LOGI和LOGE宏,分别等同于Log.i和Log.e。你可能定义自己的wrapper,使得可以在非安卓代码简单的使用它们。

Summary

能够测量性能是优化的一个简单但是关键的功能,Android提供了简单但是功能的强大的工具帮助你。Traceview,不管是为Java或者native tracing,对你来说是最有用的工具,但是要记住真实设备上实际的测量才会给出一个明确的答案,因为Traceview关闭了JIT编译器。更加深入的考虑,这些话题很重要,你需要使用Android提供的不同工具。你同样需要经常检查SDK新版本的新的工具,可以提升你的分析、测量和调试能力。记得在开始优化之前首先找到瓶颈在哪里,因为你需要集中精力于确实需要优化的部分。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值