page.title=Using DDMS parent.title=Debugging parent.link=index.html @jd:body
Android Studio includes a debugging tool called the Dalvik Debug Monitor Server (DDMS), which provides port-forwarding services, screen capture on the device, thread and heap information on the device, logcat, process, and radio state information, incoming call and SMS spoofing, location data spoofing, and more. This page provides a modest discussion of DDMS features; it is not an exhaustive exploration of all the features and capabilities.
DDMS is integrated into Android Studio. To use it, launch the Android Device Monitor, and click the DDMS menu button. DDMS works with both the emulator and a connected device. If both are connected and running simultaneously, DDMS defaults to the emulator.
On Android, every application runs in its own process, each of which runs in its own virtual machine (VM). Each VM exposes a unique port that a debugger can attach to.
When DDMS starts, it connects to adb.
When a device is connected, a VM monitoring service is created between
adb
and DDMS, which notifies DDMS when a VM on the device is started or terminated. Once a VM
is running, DDMS retrieves the VM's process ID (pid), via adb
, and opens a connection to the
VM's debugger, through the adb daemon (adbd) on the device. DDMS can now talk to the VM using a
custom wire protocol.
DDMS assigns a debugging port to each VM on the device. Typically, DDMS assigns port 8600 for the first debuggable VM, the next on 8601, and so on. When a debugger connects to one of these ports, all traffic is forwarded to the debugger from the associated VM. You can only attach a single debugger to a single port, but DDMS can handle multiple, attached debuggers.
By default, DDMS also listens on another debugging port, the DDMS "base port" (8700, by default). The base port is a port forwarder, which can accept VM traffic from any debugging port and forward it to the debugger on port 8700. This allows you to attach one debugger to port 8700, and debug all the VMs on a device. The traffic that is forwarded is determined by the currently selected process in the DDMS Devices view.
The following screenshot shows a typical DDMS screen. If you are starting DDMS from
the command line, the screen is slightly different, but much of the functionality is identical.
Notice that the highlighted process, com.android.email
, that is running in the emulator
has the debugging port 8700 assigned to it as well as 8606. This signifies that DDMS is currently
forwarding port 8606 to the static debugging port of 8700.
If you are using the command line, read Configuring your IDE to attach to the debugging port, for more information on attaching your debugger.
Tip: You can set a number of DDMS preferences in
File > Preferences. Preferences are saved to
$HOME/.android/ddms.cfg
.
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 allows you to view how much heap memory a process is using. This information is useful in tracking heap usage at a certain point of time during the execution of your application.
To view heap usage for a process:
DDMS provides a feature to track objects that are being allocated to memory and to see which classes and threads are allocating the objects. This allows you to track, in real time, where objects are being allocated when you perform certain actions in your application. This information is valuable for assessing memory usage that can affect application performance.
To track memory allocation of objects:
DDMS provides a File Explorer tab that allows you to view, copy, and delete files on the device. This feature is useful in examining files that are created by your application or if you want to transfer files to and from the device.
To work with an emulator or device's file system:
The Threads tab in DDMS shows you the currently running threads for a selected process.
Method profiling is a means to track certain metrics about a method, such as number of calls, execution time, and time spent executing the method. If you want more granular control over where profiling data is collected, use the {@link android.os.Debug#startMethodTracing()} and {@link android.os.Debug#stopMethodTracing()} methods. For more information about generating trace logs, see Profiling and Debugging UIs.
Before you start method profiling in DDMS, be aware of the following restrictions:
To start method profiling:
In Android 4.0, the DDMS (Dalvik Debug Monitor Server) includes a Detailed Network Usage tab that makes it possible to track when your application is making network requests. Using this tool, you can monitor how and when your app transfers data and optimize the underlying code appropriately. You can also distinguish between different traffic types by applying a “tag” to network sockets before use.
These tags are shown in a stack area chart in DDMS, as shown in figure 2:
By monitoring the frequency of your data transfers, and the amount of data transferred during each connection, you can identify areas of your application that can be made more battery-efficient. Generally, you should look for short spikes that can be delayed, or that should cause a later transfer to be pre-empted.
To better identify the cause of transfer spikes, the {@link android.net.TrafficStats} API allows you to tag the data transfers occurring within a thread using {@link android.net.TrafficStats#setThreadStatsTag setThreadStatsTag()}, followed by manually tagging (and untagging) individual sockets using {@link android.net.TrafficStats#tagSocket tagSocket()} and {@link android.net.TrafficStats#untagSocket untagSocket()}. For example:
TrafficStats.setThreadStatsTag(0xF00D); TrafficStats.tagSocket(outputSocket); // Transfer data using socket TrafficStats.untagSocket(outputSocket);
Alternatively, the {@link java.net.URLConnection} APIs included in the platform automatically tag sockets internally based on the active tag (as identified by {@link android.net.TrafficStats#getThreadStatsTag getThreadStatsTag()}). These APIs correctly tag/untag sockets when recycled through keep-alive pools. In the following example, {@link android.net.TrafficStats#setThreadStatsTag setThreadStatsTag()} sets the active tag to be {@code 0xF00D}. There can only be one active tag per thread. That is the value that will be returned by {@link android.net.TrafficStats#getThreadStatsTag getThreadStatsTag()} and thus used by the HTTP client to tag sockets. The {@code finally} statement invokes {@link android.net.TrafficStats#clearThreadStatsTag clearThreadStatsTag()} to clear the tag.
TrafficStats.setThreadStatsTag(0xF00D); try { // Make network request using your http client. } finally { TrafficStats.clearThreadStatsTag(); }
Socket tagging is supported in Android 4.0, but real-time stats will only be displayed on devices running Android 4.0.3 or higher.
LogCat is integrated into DDMS, and outputs the messages that you print out using the {@link android.util.Log} class along with other system messages such as stack traces when exceptions are thrown. View the Reading and Writing Log Messages. topic for more information on how to log messages to the LogCat.
When you have set up your logging, you can use the LogCat feature of DDMS to filter certain messages with the following buttons:
You can also setup your own custom filter to specify more details such as filtering messages with the log tags or with the process id that generated the log message. The add filter, edit filter, and delete filter buttons let you manage your custom filters.
The Emulator control tab lets you simulate a phone's voice and data network status. This is useful when you want to test your application's robustness in differing network environments.
The Telephony Status section of the Emulator controls tab lets you change different aspects of the phone's networks status, speed and latency. The following options are available to you and are effective immediately after you set them:
The Telephony Actions section of the Emulator controls tab lets you spoof calls and messages. This is useful when you want to to test your application's robustness in responding to incoming calls and messages that are sent to the phone. The following actions are available to you:
If your application depends on the location of the phone, you can have DDMS send your device or AVD a mock location. This is useful if you want to test different aspects of your application's location specific features without physically moving. The following geolocation data types are available to you: