On Android, debuggers communicate with the virtual machine using JDWP. When debugging is enabled, the VM creates a dedicated thread that listens for JDWP traffic and responds to requests. (It's also possible to use a native debugger, such as gdb, but that's a different kettle of fish.)
On devices sold to consumers, there's generally no need to have the extra thread running, so by default apps are not debuggable. Also, malware could potentially use the debugger interface to examine or manipulate running apps, so it's safest to disable it. On the other hand, anything running on an emulator should be debuggable, so the default behavior there is different. The ro.debuggable
system property determines this (adb shell getprop ro.debuggable
).
The debuggable
flag in the app manifest tells the VM that the app is under development, and connections from debuggers should be allowed whether or not the app is running on a production device.
All of the above relates to the app's runtime behavior, not the build. Debug builds are also different from release builds. Passing the -g
flag to javac
causes additional information to be output, and there are dx
options that will strip or keep additional debug information in the .dex
file. (I don't know how the gradle flag interacts with these.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…