Android Studio 中包含一个叫做 Dalvik Debug Monitor Server (DDMS) 的调试工具, 它具备端口映射,屏幕截图,获取设备线程和堆信息、日志、进程、无线状态信息等多个功能,还可以模拟通话、短信、位置信息等等。本文会对DDMS的功能做一个适当的介绍,关于DDMS全面详尽的功能和特性请自行了解。
DDMS 被整合进了 Android Studio,如果要使用它,要先运行 Android Device Monitor 然后点击DDMS。DDMS可以在模拟器或者Android设备上工作,如果电脑同时连接了设备又打开了模拟器,那么DDMS会优先选择模拟器。
在Android系统中,每个应用都运行在自己的进程里,每个进程都运行在自己的虚拟机(VM)中,每个VM都会暴露出一个特殊的端口,调试工具通过这个端口可以连接进程。
当DDMS启动时,它会先连接adb,当设备连接时,VM监听服务会在adb和DDMS之间被创建,当设备中的一个VM启动或者终止时,这个服务会向DDMS发送通知。当VM运行时,DDMS会通过adb检索VM的进程ID(pid),并通过设备中的adb守护进程(adbd)连接VM调试工具,此时DDMS会告知VM可以使用自定义协议。
DDMS为设备中的每个VM分配了一个调试端口, 第一个可调式的VM端口为8600,然后为8601,以此类推,当调试工具连接了其中一个端口时,所有的通信会从这个端口关联的VM转向调试工具,一个调试工具只能连接一个端口,但DDMS可以使其连接多个端口。
默认情况下,DDMS也会监听另外一个调试端口——DDMS基本端口(默认为8700),这个端口是一个映射,它可以接收任意一个VM的调试端口的通信并将其转到调试工具上的8700端口,这就可以让我们在将调试工具连接到8700端口之后对所有设备上的VM进行调试,而当前8700端口通信连接的哪个VM取决于我们在DDMS设备视图中选择的是哪个进程。
下面的截图显示了一个典型的DDMS窗口,如果你从命令行开启的DDMS,窗口会略微有些不同,但大多数功能是相同的。注意当前选择的那个com.android.systemui进程,它的调试端口为8606,同时也映射到了8700端口之上。
如果使用的命令行开启的DDMS,请阅读 Configuring your IDE to attach to the debugging port 以获取更多信息。
小贴士: 你可以在File > Preferences中设置DDMS的个人偏好,其保存在 $HOME/.android/ddms.cfg
已知的用 Dalvik 调试会遇到的问题
在Dalvik VM中调试一个应用应该和在其他VM中相同,然而,在同步代码外的单步操作中,当前行的cursor会直接跳到最后一行。 (不知道什么意思,贴上原文)。
Known debugging issues with Dalvik
Debugging an application in the Dalvik VM should work the same as it does in other VMs. However, when single-stepping out of synchronized code, the "current line" cursor may jump to the last line in the method for one step.
DDMS可以查看一个进程正在使用多少堆内存,在应用运行时,这个信息对于追踪一个时间点的堆使用很有用。
查看进程堆使用情况的步骤:
DDMS 提供了一个功能来追踪对象被分配了多少内容,以及查看哪些类和线程分配了这些对象。这可以在实际中让我们追踪当执行应用中的功能时,对象在哪里被创建以及创建了多少,在应用性能受到内存使用影响时,这个信息十分有用。
追踪对象内存分配的步骤:
DDMS 提供了一个 File Explorer 标签来让我们查看,复制或删除设备中的文件,这个功能对于检查应用创建的文件、从设备中复制文件出来、复制文件到设备中很有用。(使用adb pull或者adb push也可以)
文件系统操作步骤:
DDMS 中的线程信息给我们展示了当前选择的进程中正在运行的线程。
方法分析是追踪方法核心调度的一个手段,例如可以追踪方法调用,执行时间,某个调用的执行时间。如果需要更细的控制分析数据的手机,需要使用 startMethodTracing()
和 stopMethodTracing()
方法,更多关于生产trace log的信息请查阅 Profiling and Debugging UIs。
在你使用 DDMS开启方法分析之前,需要知道以下限制:
方法分析的步骤:
在 Android 4.0 中,DDMS (Dalvik Debug Monitor Server) 包含一个网络使用细节标签页,它可以追踪应用在什么时候发送了网络请求,使用这个工具,我们可以监视应用传输数据的时间以及如何传送的数据,并会自动完善潜在的代码。我们也可以在使用之前通过申请一个网络包的标签来区分不同的通信类型。
这些标签显示在DDMS中的堆区域图表中,如图2所示:
通过监视每次连接时数据传送的频率及大小,可以确认应用的使用情况以使应用更加高效,通常,我们应该观察short spikes,它会有延迟或者会在获得之前推迟传送。
为了更好地确认造成传送spikes的原因,我们可以使用 TrafficStats
API ,使用其中的 setThreadStatsTag()
allows 方法可以让我们为发生在线程中的网络通信打标签,为单独的包打标签或者去掉标签可以使用 tagSocket()
和 untagSocket()
。例:
TrafficStats.setThreadStatsTag(0xF00D); TrafficStats.tagSocket(outputSocket); // Transfer data using socket TrafficStats.untagSocket(outputSocket);
开发环境中的 URLConnection
APIs 会自动为已经打了标签的(可以用getThreadStatsTag()
方法来确认)内部的包打上标签,这些API在激活的线程池刷新时会为包正确的打标签/解除标签。下面的例子中,setThreadStatsTag()
设置了激活的标签为 0xF00D
。每个线程中只能有一个激活的标签, 这个标签是一个值,在 getThreadStatsTag()
方法中可以返回然后在HTTP客户端中使用可以给包打标签,调用 clearThreadStatsTag()
可以清楚标签。
TrafficStats.setThreadStatsTag(0xF00D); try { // Make network request using your http client. } finally { TrafficStats.clearThreadStatsTag(); }
Android 4.0支持包的标签,但实际上必须要在Android 4.0.3或更高版本上才可以显示。
LogCat 被整合进了 DDMS,它可以输出用Log类打印出的信息以及其他系统信息,例如发生异常时的stack trace,查阅 Reading and Writing Log Messages以了解更多关于LogCat中如何打Log的信息。
当你查看Log时,可以使用DDMS中LogCat中功能来过滤信息,按钮如下:
也可以设置自己的过滤器,比如标签、进程号等等,标签的增删改可以让我们更好的管理过滤器。
图1中的 Emulator Control 标签已经不再支持了,现在是要使用 Android Emulator 来实现这些功能。